pax_global_header00006660000000000000000000000064125574503410014520gustar00rootroot0000000000000052 comment=8f06fc9d92fcea2d36491448be804c14807e292f libnfs-libnfs-1.9.8/000077500000000000000000000000001255745034100142675ustar00rootroot00000000000000libnfs-libnfs-1.9.8/.gitignore000066400000000000000000000006401255745034100162570ustar00rootroot00000000000000.* *.h *.c *.in *.la *.a *.lo *.o *.obj *.lib *.dll *.ilk *.pdb *.ex? *-stamp libnfs-raw-*.x Makefile examples/nfsclient-raw examples/nfsclient-sync examples/nfsclient-async examples/nfsclient-bcast examples/nfsclient-listservers aclocal.m4 autom4te.cache/ compile config.guess config.h.in~ config.log config.status config.sub configure depcomp install-sh libtool ltmain.sh missing stamp-h1 libnfs.pc !libnfs.pc.in libnfs-libnfs-1.9.8/COPYING000066400000000000000000000017221255745034100153240ustar00rootroot00000000000000Libnfs components fall under two separate licences The library sources and include directories =========================================== The nfs client library itself, i.e. the lib and include directories, is licenced under 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. The protocol definition, .x, files ================================== These are based on old RFCs and studying how wireshark dissects various packets. These are distributed under the simplified BSD licence. The examples directory ================================ The utility and example applications using this library, i.e. the examples directory, are licenced under 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. To avoid any confusion, every source file contains a licence boilerplate. libnfs-libnfs-1.9.8/LICENCE-BSD.txt000066400000000000000000000026611255745034100165050ustar00rootroot00000000000000Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. libnfs-libnfs-1.9.8/LICENCE-GPL-3.txt000066400000000000000000001045131255745034100166560ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. 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. Copyright (C) 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 . 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: Copyright (C) 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 . 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 . libnfs-libnfs-1.9.8/LICENCE-LGPL-2.1.txt000066400000000000000000000636421255745034100171370ustar00rootroot00000000000000 GNU LESSER GENERAL PUBLIC LICENSE Version 2.1, February 1999 Copyright (C) 1991, 1999 Free Software Foundation, Inc. 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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. 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. 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. 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. 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. 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. 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. 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. 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 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. Copyright (C) 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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. , 1 April 1990 Ty Coon, President of Vice That's all there is to it! libnfs-libnfs-1.9.8/Makefile.am000066400000000000000000000004531255745034100163250ustar00rootroot00000000000000SUBDIRS = doc mount nfs nlm nsm portmap rquota lib include utils . $(MAYBE_EXAMPLES) ACLOCAL_AMFLAGS = -I m4 pkgconfigdir = $(libdir)/pkgconfig pkgconfig_DATA = libnfs.pc EXTRA_DIST = \ README \ COPYING \ LICENCE-BSD.txt \ LICENCE-GPL-3.txt \ LICENCE-LGPL-2.1.txt \ examples \ libnfs.pc.in libnfs-libnfs-1.9.8/README000066400000000000000000000127521255745034100151560ustar00rootroot00000000000000LIBNFS is a client library for accessing NFS shares over a network. LIBNFS offers three different APIs, for different use : 1, RAW : A fully async low level RPC library for NFS protocols This API is described in include/libnfs-raw.h it offers a fully async interface to raw XDR encoded blobs. This API provides very flexible and precise control of the RPC issued. examples/nfsclient-raw.c provides examples on how to use the raw API 2, NFS ASYNC : A fully asynchronous library for high level vfs functions This API is described by the *_async() functions in include/libnfs.h. This API provides a fully async access to posix vfs like functions such as stat(), read(), ... examples/nfsclient-async.c provides examples on how to use this API 3, NFS SYNC : A synchronous library for high level vfs functions This API is described by the *_sync() functions in include/libnfs.h. This API provides access to posix vfs like functions such as stat(), read(), ... examples/nfsclient-sync.c provides examples on how to use this API URL-FORMAT: =========== Libnfs uses RFC2224 style URLs extended with libnfs specific url arguments some minor extensions. The basic syntax of these URLs is : nfs:///path[?arg=val[&arg=val]*] Arguments supported by libnfs are : tcp-syncnt= : Number of SYNs to send during the session establish before failing setting up the tcp connection to the server. uid= : UID value to use when talking to the server. default it 65534 on Windows and getuid() on unixen. gid= : GID value to use when talking to the server. default it 65534 on Windows and getgid() on unixen. readahead= : Enable readahead for files and set the maximum amount of readahead to . auto-traverse-mounts=<0|1> : Should libnfs try to traverse across nested mounts automatically or not. Default is 1 == enabled. Auto_traverse_mounts ==================== Normally in NFSv3 if a server has nested exports, for example if it would export both /data and /data/tmp then a client would need to mount both these exports as well. The reason is because the NFSv3 protocol does not allow a client request to return data for an object in a different filesystem/mount. (legacy, but it is what it is. One reason for this restriction is to guarantee that inodes are uniqe across the mounted system.) This option, when enabled will make libnfs perform all these mounts internally for you. This means that one libnfs mount may now have files with duplicate inode values so if you cache files based on inode make sure you cache files based on BOTH st.st_ino and st.st_dev. ROOT vs NON-ROOT ================ When running as root, libnfs tries to allocate a system port for its connection to the NFS server. When running as non-root it will use a normal ephemeral port. Many NFS servers default to a mode where they do not allow non-system ports from connecting. These servers require you use the "insecure" export option in /etc/exports in order to allow libnfs clients to be able to connect. Some versions of Linux support special capabilities that can be assigned to programs to allow non-root users to bind to system ports. This is set up by running sudo setcap 'cap_net_bind_service=+ep' /path/to/executable When libnfs is linked against an executable with this special capability assigned to it, libnfs may be able to use system ports even when executing under the privilege of a non-root user account. This is highly non-portable so IF this works on your linux system, count yourself lucky. DOCUMENTATION ============= libnfs sources ship with prebuilt manpage(s) in the doc directory. If you change the manpage sources you need to manually regenerate the new manpages by running cd doc make doc FUSE ==== A simple FUSE filesystem built on libnfs can be found in examples/fuse_nfs.c Compile using : gcc fuse_nfs.c -o fuse_nfs -lfuse -lnfs Mount using : sudo ./fuse_nfs -n nfs:/// -m PLATFORM support ================= This is a truly multiplatform library. Linux: - tested with Ubuntu 10.04 - should work with others as well Cygwin: - tested under 64bit win2k8. MacOSX: - tested with SDK 10.4 (under Snow Leopard) - should also work with later SDKs and 64Bit iOS: - tested with iOS SDK 4.2 - running on iOS 4.3.x FreeBSD:- tested with 8.2 Solaris Windows:- tested on Windows 7 64 and Windows XP 32 using Visual Studio 10 (see README.win32.txt for build instructions) Android: AROS: - Build with 'make -f aros/Makefile.AROS' LD_PRELOAD ========== examples/ld_nfs.c contains a LD_PRELOADable module that can be used to make several standard utilities nfs aware. It is still very incomplete but can be used for basic things such as cat and cp. Patches to add more coverage is welcome. Compile with : gcc -fPIC -shared -o ld_nfs.so examples/ld_nfs.c -ldl -lnfs Then try things like LD_NFS_DEBUG=9 LD_PRELOAD=./ld_nfs.so cat nfs://127.0.0.1/data/tmp/foo123 LD_NFS_DEBUG=9 LD_PRELOAD=./ld_nfs.so cp nfs://127.0.0.1/data/tmp/foo123 nfs://127.0.0.1/data/tmp/foo123.copy This is just a toy preload module. Don't open bugs if it does not work. Send patches to make it better instead. RELEASE TARBALLS ================ Release tarballs are available at https://sites.google.com/site/libnfstarballs/li MAILING LIST ============ A libnfs mailing list is available at http://groups.google.com/group/libnfs Announcements of new versions of libnfs will be posted to this list. libnfs-libnfs-1.9.8/aros/000077500000000000000000000000001255745034100152335ustar00rootroot00000000000000libnfs-libnfs-1.9.8/aros/Makefile.AROS000077500000000000000000000027371255745034100174520ustar00rootroot00000000000000AR=ar CC=gcc CFLAGS=-g -O0 -DAROS=1 -D_U_=" " -DHAVE_SOCKADDR_LEN -I. -Iinclude -Iinclude/nfsc -Iaros -Infs -Imount OBJS=lib/init.o lib/libnfs.o lib/libnfs-sync.o lib/libnfs-zdr.o lib/pdu.o lib/socket.o OBJS+=mount/mount.o mount/libnfs-raw-mount.o OBJS+=nfs/nfs.o nfs/nfsacl.o nfs/libnfs-raw-nfs.o OBJS+=nlm/nlm.o nlm/libnfs-raw-nlm.o OBJS+=portmap/portmap.o portmap/libnfs-raw-portmap.o OBJS+=rquota/rquota.o rquota/libnfs-raw-rquota.o OBJS+=aros/aros_compat.o EXAMPLES=examples/nfsclient-listservers examples/nfsclient-sync examples/nfs-cp examples/nfs-ls all: lib/libnfs.a $(EXAMPLES) lib/libnfs.a: $(OBJS) $(AR) cru $@ $(OBJS) .c.o: echo $(CC) $(CFLAGS) -c -o $@ $< $(CC) $(CFLAGS) -c -o $@ $< install: all cp lib/libnfs.a GCC:lib mkdir -p INCLUDE:nfsc cp include/nfsc/libnfs.h INCLUDE:nfsc cp include/nfsc/libnfs-raw.h INCLUDE:nfsc cp include/nfsc/libnfs-zdr.h INCLUDE:nfsc cp mount/libnfs-raw-mount.h INCLUDE:nfsc cp nlm/libnfs-raw-nlm.h INCLUDE:nfsc cp nfs/libnfs-raw-nfs.h INCLUDE:nfsc cp portmap/libnfs-raw-portmap.h INCLUDE:nfsc cp rquota/libnfs-raw-rquota.h INCLUDE:nfsc examples/nfsclient-listservers: examples/nfsclient-listservers.c lib/libnfs.a $(CC) $(CFLAGS) -o $@ $< lib/libnfs.a examples/nfsclient-sync: examples/nfsclient-sync.c lib/libnfs.a $(CC) $(CFLAGS) -o $@ $< lib/libnfs.a examples/nfs-ls: examples/nfs-ls.c lib/libnfs.a $(CC) $(CFLAGS) -o $@ $< lib/libnfs.a examples/nfs-cp: examples/nfs-cp.c lib/libnfs.a $(CC) $(CFLAGS) -o $@ $< lib/libnfs.a libnfs-libnfs-1.9.8/aros/aros_compat.c000066400000000000000000000101231255745034100177030ustar00rootroot00000000000000/* Copyright (C) 2013 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #include #include #include #include #include #include #include #include "aros_compat.h" #include #include #undef poll int aros_getnameinfo(const struct sockaddr *sa, socklen_t salen, char *host, size_t hostlen, char *serv, size_t servlen, int flags) { struct sockaddr_in *sin = (struct sockaddr_in *)sa; if (host) { snprintf(host, hostlen, Inet_NtoA(sin->sin_addr.s_addr)); } return 0; } int aros_getaddrinfo(const char *node, const char*service, const struct addrinfo *hints, struct addrinfo **res) { struct sockaddr_in *sin; sin = malloc(sizeof(struct sockaddr_in)); sin->sin_len = sizeof(struct sockaddr_in); sin->sin_family=AF_INET; /* Some error checking would be nice */ sin->sin_addr.s_addr = inet_addr(node); sin->sin_port=0; if (service) { sin->sin_port=htons(atoi(service)); } *res = malloc(sizeof(struct addrinfo)); (*res)->ai_family = AF_INET; (*res)->ai_addrlen = sizeof(struct sockaddr_in); (*res)->ai_addr = (struct sockaddr *)sin; return 0; } void aros_freeaddrinfo(struct addrinfo *res) { free(res->ai_addr); free(res); } int aros_inet_pton(int af, char *src, void *dst) { struct sockaddr_in sin; sin.sin_addr.s_addr = inet_addr(src); memcpy(dst, &sin.sin_addr.s_addr, sizeof(sin.sin_addr.s_addr)); return 1; } /* unix device numbers dont really make much sense on aros ... */ int major(int i) { return 1; } int minor(int i) { return 2; } struct Library * SocketBase = NULL; extern int errno; int h_errno = 0; void aros_init_socket(void) { if (!(SocketBase = OpenLibrary("bsdsocket.library", 4))) { printf("NoTCP/IP Stack available"); exit(10); } if (SocketBaseTags(SBTM_SETVAL(SBTC_ERRNOPTR(sizeof(errno))), (IPTR)&errno, SBTM_SETVAL(SBTC_HERRNOLONGPTR), (IPTR)&h_errno, TAG_DONE)) { printf("Failed to set ERRNO"); exit(10); } } int aros_poll(struct pollfd *fds, unsigned int nfds, int timo) { struct timeval timeout, *toptr; fd_set ifds, ofds, efds, *ip, *op; unsigned int i, maxfd = 0; int rc; // Set up the file-descriptor sets in ifds, ofds and efds. FD_ZERO(&ifds); FD_ZERO(&ofds); FD_ZERO(&efds); for (i = 0, op = ip = 0; i < nfds; ++i) { fds[i].revents = 0; if(fds[i].events & (POLLIN|POLLPRI)) { ip = &ifds; FD_SET(fds[i].fd, ip); } if(fds[i].events & POLLOUT) { op = &ofds; FD_SET(fds[i].fd, op); } FD_SET(fds[i].fd, &efds); if (fds[i].fd > maxfd) { maxfd = fds[i].fd; } } // Set up the timeval structure for the timeout parameter if(timo < 0) { toptr = 0; } else { toptr = &timeout; timeout.tv_sec = timo / 1000; timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000; } rc = WaitSelect(maxfd + 1, ip, op, &efds, toptr, NULL); if(rc <= 0) return rc; if(rc > 0) { for (i = 0; i < nfds; ++i) { int fd = fds[i].fd; if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) fds[i].revents |= POLLIN; if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) fds[i].revents |= POLLOUT; if(FD_ISSET(fd, &efds)) // Some error was detected ... should be some way to know. fds[i].revents |= POLLHUP; } } return rc; } libnfs-libnfs-1.9.8/aros/aros_compat.h000066400000000000000000000040531255745034100177150ustar00rootroot00000000000000/* Copyright (C) 2013 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifndef AROS_COMPAT_H #define AROS_COMPAT_H #include #include #include #include #include #include #include #include #include #include #define statvfs statfs #define ioctl IoctlSocket #define close CloseSocket #define inet_pton aros_inet_pton #define freeaddrinfo aros_freeaddrinfo #define getnameinfo aros_getnameinfo #define getaddrinfo aros_getaddrinfo extern struct Library * SocketBase; void aros_init_socket(void); #define f_flag f_flags #define f_favail f_ffree /* we dont have these at all */ #define f_fsid f_spare[0] #define f_frsize f_spare[0] #define f_namemax f_spare[0] #define POLLIN 0x0001 /* There is data to read */ #define POLLPRI 0x0002 /* There is urgent data to read */ #define POLLOUT 0x0004 /* Writing now will not block */ #define POLLERR 0x0008 /* Error condition */ #define POLLHUP 0x0010 /* Hung up */ #define POLLNVAL 0x0020 /* Invalid request: fd not open */ struct utimbuf { int actime; int modtime; }; struct pollfd { int fd; /* file descriptor */ short events; /* requested events */ short revents; /* returned events */ }; #define poll(x, y, z) aros_poll(x, y, z) #endif libnfs-libnfs-1.9.8/bootstrap000077500000000000000000000000361255745034100162310ustar00rootroot00000000000000#!/bin/bash autoreconf -vif libnfs-libnfs-1.9.8/configure.ac000066400000000000000000000111241255745034100165540ustar00rootroot00000000000000AC_PREREQ(2.50) AC_INIT([libnfs], [1.9.8], [ronniesahlberg@gmail.com]) AC_CONFIG_HEADERS([config.h]) AM_INIT_AUTOMAKE([-Wall foreign]) AC_CANONICAL_HOST AC_CONFIG_MACRO_DIR([m4]) m4_pattern_allow([AM_PROG_AR]) AM_PROG_AR # Work around stupid autoconf default cflags. pt 1 SAVE_CFLAGS="x${CFLAGS}" AC_PROG_CC AC_PROG_LIBTOOL AM_PROG_CC_C_O PKG_PROG_PKG_CONFIG # Work around stupid autoconf default cflags. pt 2 if test "$SAVE_CFLAGS" = "x"; then CFLAGS="" fi # We always want 64 bit file offsets CFLAGS="${CFLAGS} -D_FILE_OFFSET_BITS=64" #option: examples AC_ARG_ENABLE([examples], [AC_HELP_STRING([--enable-examples], [Build example programs])], [ENABLE_EXAMPLES=$enableval], [ENABLE_EXAMPLES="no"]) # We need popt to compile the examples if test x$ENABLE_EXAMPLES = xyes; then AC_MSG_CHECKING(whether libpopt is available) ac_save_CFLAGS="$CFLAGS" ac_save_LIBS="$LIBS" CFLAGS="$CFLAGS $GLIB_CFLAGS" LIBS="$GLIB_LIBS $LIBS -lpopt" AC_TRY_RUN([ /* * Just see if we can compile/link with popt */ #include int main(int argc, const char *argv[]) { struct poptOption popt_options[] = { POPT_TABLEEND }; poptGetContext(argv[0], argc, argv, popt_options, POPT_CONTEXT_KEEP_FIRST); return 0; } ], ac_cv_have_popt=yes, ac_cv_have_popt=no, [echo $ac_n "compile with POPT. Assuming OK... $ac_c" ac_cv_have_popt=yes]) CFLAGS="$ac_save_CFLAGS" LIBS="$ac_save_LIBS" if test "$ac_cv_have_popt" = yes ; then AC_MSG_RESULT(yes) MAYBE_EXAMPLES="examples" else AC_MSG_RESULT(no) AC_MSG_NOTICE(You need libpopt to compile the sample libnfs clients.) AC_MSG_NOTICE(Only the library will be compiled and installed.) fi fi AC_SUBST(MAYBE_EXAMPLES) WERROR_CFLAGS="" AC_MSG_CHECKING(whether to set -Werror) AC_ARG_ENABLE(werror, [ --disable-werror do not treat warnings as errors during build], [ case "${enableval}" in no) AC_MSG_RESULT(no) ;; *) AC_MSG_RESULT(yes) WERROR_CFLAGS="-Werror" ;; esac ], ) if test "$ac_cv_prog_gcc" = yes; then WARN_CFLAGS="-Wall -Wshadow -Wno-write-strings -Wstrict-prototypes -Wpointer-arith -Wcast-align -Wno-strict-aliasing $WERROR_CFLAGS" fi AC_SUBST(WARN_CFLAGS) case $host in *solaris*) AC_CHECK_HEADERS([sys/filio.h]) AC_CHECK_HEADERS([sys/sockio.h]) AC_CHECK_LIB([socket], [main], , [AC_MSG_ERROR([Can not find required library])]) AC_CHECK_LIB([nsl], [main], , [AC_MSG_ERROR([Can not find required library])]) ;; *) ;; esac # check for poll.h dnl Check for poll.h AC_CHECK_HEADERS([poll.h]) # check for unistd.h dnl Check for unistd.h AC_CHECK_HEADERS([unistd.h]) # check for netdb.h dnl Check for netdb.h AC_CHECK_HEADERS([netdb.h]) # check for utime.h dnl Check for utime.h AC_CHECK_HEADERS([utime.h]) # check for net/if.h dnl Check for net/if.h AC_CHECK_HEADERS([net/if.h]) # check for sys/time.h dnl Check for sys/time.h AC_CHECK_HEADERS([sys/time.h]) # check for sys/ioctl.h dnl Check for sys/ioctl.h AC_CHECK_HEADERS([sys/ioctl.h]) # check for sys/vfs.h dnl Check for sys/vfs.h AC_CHECK_HEADERS([sys/vfs.h]) # check for sys/statvfs.h dnl Check for sys/statvfs.h AC_CHECK_HEADERS([sys/statvfs.h]) # check for sys/socket.h dnl Check for sys/socket.h AC_CHECK_HEADERS([sys/socket.h]) # check for netinet/tcp.h dnl Check for netinet/tcp.h AC_CHECK_HEADERS([netinet/tcp.h]) # check for netinet/in.h dnl Check for netinet/in.h AC_CHECK_HEADERS([netinet/in.h]) # check for arpa/inet.h dnl Check for arpa/inet.h AC_CHECK_HEADERS([arpa/inet.h]) # check for SA_LEN dnl Check if sockaddr data structure includes a "sa_len" AC_CHECK_MEMBER([struct sockaddr.sa_len], [ AC_DEFINE(HAVE_SOCKADDR_LEN,1,[Whether sockaddr struct has sa_len]) ], [], [ #include #include ]) # check for sockaddr_storage dnl Check if sockaddr structure includes a "ss_family" AC_CHECK_MEMBER([struct sockaddr_storage.ss_family], [ AC_DEFINE(HAVE_SOCKADDR_STORAGE,1,[Whether we have sockaddr_Storage]) ], [], [ #include #include ]) AC_CHECK_MEMBERS([struct stat.st_mtim.tv_nsec]) # check where makedev is defined AC_HEADER_MAJOR #output AC_CONFIG_FILES([Makefile] [doc/Makefile] [include/Makefile] [lib/Makefile] [mount/Makefile] [nfs/Makefile] [nlm/Makefile] [nsm/Makefile] [portmap/Makefile] [rquota/Makefile] [utils/Makefile] [examples/Makefile] ) AC_OUTPUT([libnfs.pc]) libnfs-libnfs-1.9.8/doc/000077500000000000000000000000001255745034100150345ustar00rootroot00000000000000libnfs-libnfs-1.9.8/doc/Makefile.am000066400000000000000000000011031255745034100170630ustar00rootroot00000000000000XSLTPROC = /usr/bin/xsltproc EXTRA_DIST = nfs-cat.1 nfs-cat.1.xml nfs-cp.1 nfs-cp.1.xml nfs-ls.1 nfs-ls.1.xml # Manpages man1_MANS = nfs-cat.1 nfs-cp.1 nfs-ls.1 doc: -test -z "$(XSLTPROC)" || $(XSLTPROC) -o nfs-cat.1 http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl nfs-cat.1.xml -test -z "$(XSLTPROC)" || $(XSLTPROC) -o nfs-cp.1 http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl nfs-cp.1.xml -test -z "$(XSLTPROC)" || $(XSLTPROC) -o nfs-ls.1 http://docbook.sourceforge.net/release/xsl/current/manpages/docbook.xsl nfs-ls.1.xml libnfs-libnfs-1.9.8/doc/nfs-cat.1000066400000000000000000000032421255745034100164520ustar00rootroot00000000000000'\" t .\" Title: nfs-cat .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 .\" Date: 05/24/2015 .\" Manual: nfs-cat: read a file from nfs .\" Source: nfs-cat .\" Language: English .\" .TH "NFS\-CAT" "1" "05/24/2015" "nfs\-cat" "nfs\-cat: read a file from nfs" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" nfs-cat \- Utility to read a file off NFS .SH "SYNOPSIS" .HP \w'\fBnfs\-cat\ \fR\ 'u \fBnfs\-cat \fR .SH "DESCRIPTION" .PP nfs\-cat is a utility to read a file off an NFS server\&. .PP Example: Print the content of a file: .sp .if n \{\ .RS 4 .\} .nf $ nfs\-cat nfs://127\&.0\&.0\&.1/data/tmp/foo\&.c .fi .if n \{\ .RE .\} .sp .SH "SEE ALSO" .PP \m[blue]\fB\%http://github.com/sahlberg/libnfs\fR\m[] libnfs-libnfs-1.9.8/doc/nfs-cat.1.xml000066400000000000000000000016761255745034100172620ustar00rootroot00000000000000 nfs-cat 1 nfs-cat nfs-cat: read a file from nfs nfs-cat Utility to read a file off NFS nfs-cat <NFS-URL> DESCRIPTION nfs-cat is a utility to read a file off an NFS server. Example: Print the content of a file: $ nfs-cat nfs://127.0.0.1/data/tmp/foo.c SEE ALSO libnfs-libnfs-1.9.8/doc/nfs-cp.1000066400000000000000000000035011255745034100163030ustar00rootroot00000000000000'\" t .\" Title: nfs-cp .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 .\" Date: 05/24/2015 .\" Manual: nfs-cp: copy files to/from an NFS share .\" Source: nfs-cp .\" Language: English .\" .TH "NFS\-CP" "1" "05/24/2015" "nfs\-cp" "nfs\-cp: copy files to/from an" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" nfs-cp \- Utility to copy files to/from and NFS server .SH "SYNOPSIS" .HP \w'\fBnfs\-cp\ \ \fR\ 'u \fBnfs\-cp \fR .SH "DESCRIPTION" .PP nfs\-cp is a utility to copy files to/from and NFS server\&. .PP Examples: .sp .if n \{\ .RS 4 .\} .nf $ nfs\-cp foo\&.c nfs://127\&.0\&.0\&.1/data/tmp/foo\&.c $ nfs\-cp nfs://127\&.0\&.0\&.1/data/tmp/foo\&.c bob\&.c $ nfs\-cp nfs://127\&.0\&.0\&.1/data/tmp/foo\&.c nfs://127\&.0\&.0\&.1/data/tmp/copy\-of\-foo\&.c .fi .if n \{\ .RE .\} .sp .SH "SEE ALSO" .PP \m[blue]\fB\%http://github.com/sahlberg/libnfs\fR\m[] libnfs-libnfs-1.9.8/doc/nfs-cp.1.xml000066400000000000000000000021041255745034100171000ustar00rootroot00000000000000 nfs-cp 1 nfs-cp nfs-cp: copy files to/from an NFS share nfs-cp Utility to copy files to/from and NFS server nfs-cp <src> <dst> DESCRIPTION nfs-cp is a utility to copy files to/from and NFS server. Examples: $ nfs-cp foo.c nfs://127.0.0.1/data/tmp/foo.c $ nfs-cp nfs://127.0.0.1/data/tmp/foo.c bob.c $ nfs-cp nfs://127.0.0.1/data/tmp/foo.c nfs://127.0.0.1/data/tmp/copy-of-foo.c SEE ALSO libnfs-libnfs-1.9.8/doc/nfs-ls.1000066400000000000000000000060031255745034100163170ustar00rootroot00000000000000'\" t .\" Title: nfs-ls .\" Author: [FIXME: author] [see http://docbook.sf.net/el/author] .\" Generator: DocBook XSL Stylesheets v1.78.1 .\" Date: 05/24/2015 .\" Manual: nfs-ls: list servers, exports and directories .\" Source: nfs-ls .\" Language: English .\" .TH "NFS\-LS" "1" "05/24/2015" "nfs\-ls" "nfs\-ls: list servers, exports" .\" ----------------------------------------------------------------- .\" * Define some portability stuff .\" ----------------------------------------------------------------- .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .\" http://bugs.debian.org/507673 .\" http://lists.gnu.org/archive/html/groff/2009-02/msg00013.html .\" ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" ----------------------------------------------------------------- .\" * set default formatting .\" ----------------------------------------------------------------- .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) .ad l .\" ----------------------------------------------------------------- .\" * MAIN CONTENT STARTS HERE * .\" ----------------------------------------------------------------- .SH "NAME" nfs-ls \- Utility to list NFS servers, exports and directories .SH "SYNOPSIS" .HP \w'\fBnfs\-ls\ [\ OPTIONS\ ]\ \fR\ 'u \fBnfs\-ls [ OPTIONS ] \fR .HP \w'\fBnfs\-ls\fR\ 'u \fBnfs\-ls\fR [\-R\ \-\-recursive] [\-s\ \-\-summary] [\-D\ \-\-discovery] [\-?\ \-\-help] [\-\-usage] .SH "DESCRIPTION" .PP nfs\-ls is a utility to list NFS servers, exports or directories\&. .PP Example: List the content of a directory on the NFS server .sp .if n \{\ .RS 4 .\} .nf $ nfs\-ls nfs://127\&.0\&.0\&.1/data/tmp \-rwxrwxr\-x 1 1000 1000 1190802 a\&.out \-rwxr\-xr\-x 1 1000 1000 13 foo123\&.copy \-rwxrwxrwx 1 1000 1000 8 foo123\&.writtenx .fi .if n \{\ .RE .\} .sp .SH "OPTIONS" .PP \-s \-\-summary .RS 4 Print a summary line at the end of output\&. .RE .PP \-R \-\-recursive .RS 4 Recursive listing of the specified URL\&. .RE .PP \-D \-\-discovery; .RS 4 This option is used to discover local NFS servers and to list the exports for specific servers\&. .sp When used with the \*(Aqnfs://\*(Aq URL the command will try to detect all local NFS servers and will list their IPs\&. .sp When used with a \*(Aqnfs://server\*(Aq the command will list all the exports on the specified server\&. .sp Example: Discover and list all local NFS servers .sp .if n \{\ .RS 4 .\} .nf $ nfs\-ls \-D nfs:// nfs://10\&.10\&.10\&.10 nfs://10\&.0\&.0\&.10 .fi .if n \{\ .RE .\} .sp Example: List the exports for a server .sp .if n \{\ .RS 4 .\} .nf $ nfs\-ls \-D nfs://10\&.10\&.10\&.10 nfs://10\&.10\&.10\&.10/foo nfs://10\&.10\&.10\&.10/bar .fi .if n \{\ .RE .\} .sp .RE .PP \-? \-\-help .RS 4 Display basic help text\&. .RE .PP \-\-usage .RS 4 Display basic usage text\&. .RE .SH "SEE ALSO" .PP \m[blue]\fB\%http://github.com/sahlberg/libnfs\fR\m[] libnfs-libnfs-1.9.8/doc/nfs-ls.1.xml000066400000000000000000000060611255745034100171220ustar00rootroot00000000000000 nfs-ls 1 nfs-ls nfs-ls: list servers, exports and directories nfs-ls Utility to list NFS servers, exports and directories nfs-ls [ OPTIONS ] <NFS-URL> nfs-ls -R --recursive -s --summary -D --discovery -? --help --usage DESCRIPTION nfs-ls is a utility to list NFS servers, exports or directories. Example: List the content of a directory on the NFS server $ nfs-ls nfs://127.0.0.1/data/tmp -rwxrwxr-x 1 1000 1000 1190802 a.out -rwxr-xr-x 1 1000 1000 13 foo123.copy -rwxrwxrwx 1 1000 1000 8 foo123.writtenx OPTIONS -s --summary Print a summary line at the end of output. -R --recursive Recursive listing of the specified URL. -D --discovery; This option is used to discover local NFS servers and to list the exports for specific servers. When used with the 'nfs://' URL the command will try to detect all local NFS servers and will list their IPs. When used with a 'nfs://server' the command will list all the exports on the specified server. Example: Discover and list all local NFS servers $ nfs-ls -D nfs:// nfs://10.10.10.10 nfs://10.0.0.10 Example: List the exports for a server $ nfs-ls -D nfs://10.10.10.10 nfs://10.10.10.10/foo nfs://10.10.10.10/bar -? --help Display basic help text. --usage Display basic usage text. SEE ALSO libnfs-libnfs-1.9.8/examples/000077500000000000000000000000001255745034100161055ustar00rootroot00000000000000libnfs-libnfs-1.9.8/examples/Makefile.am000066400000000000000000000006211255745034100201400ustar00rootroot00000000000000noinst_PROGRAMS = nfsclient-async nfsclient-raw nfsclient-sync nfsclient-bcast nfsclient-listservers nfs-io portmap-client AM_CPPFLAGS = \ -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc \ -I$(abs_top_srcdir)/mount \ -I$(abs_top_srcdir)/nfs \ -I$(abs_top_srcdir)/portmap \ -I$(abs_top_srcdir)/rquota \ "-D_U_=__attribute__((unused))" AM_LDFLAGS = ../lib/.libs/libnfs.la -lpopt libnfs-libnfs-1.9.8/examples/fuse_nfs.c000066400000000000000000000155621255745034100200720ustar00rootroot00000000000000/* Copyright (C) by Ronnie Sahlberg 2013 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 . */ /* A FUSE filesystem based on libnfs. */ #define FUSE_USE_VERSION 26 #define _FILE_OFFSET_BITS 64 #include #include #include #include #include #include #include #include #define discard_const(ptr) ((void *)((intptr_t)(ptr))) struct nfs_context *nfs = NULL; static int fuse_nfs_getattr(const char *path, struct stat *stbuf) { int ret = 0; struct nfs_stat_64 nfs_st; ret = nfs_stat64(nfs, path, &nfs_st); stbuf->st_dev = nfs_st.nfs_dev; stbuf->st_ino = nfs_st.nfs_ino; stbuf->st_mode = nfs_st.nfs_mode; stbuf->st_nlink = nfs_st.nfs_nlink; stbuf->st_uid = nfs_st.nfs_uid; stbuf->st_gid = nfs_st.nfs_gid; stbuf->st_rdev = nfs_st.nfs_rdev; stbuf->st_size = nfs_st.nfs_size; stbuf->st_blksize = nfs_st.nfs_blksize; stbuf->st_blocks = nfs_st.nfs_blocks; stbuf->st_atim.tv_sec = nfs_st.nfs_atime; stbuf->st_atim.tv_usec = nfs_st.nfs_atime_nsec / 1000; stbuf->st_mtim.tv_sec = nfs_st.nfs_mtime; stbuf->st_mtim.tv_usec = nfs_st.nfs_mtime_nsec / 1000; stbuf->st_ctim.tv_sec = nfs_st.nfs_ctime; stbuf->st_ctim.tv_usec = nfs_st.nfs_ctime_nsec / 1000; return ret; } static int fuse_nfs_readdir(const char *path, void *buf, fuse_fill_dir_t filler, off_t offset, struct fuse_file_info *fi) { struct nfsdir *nfsdir; struct nfsdirent *nfsdirent; int ret = 0; ret = nfs_opendir(nfs, path, &nfsdir); if (ret < 0) { return ret; } while ((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { filler(buf, nfsdirent->name, NULL, 0); } return ret; } static int fuse_nfs_open(const char *path, struct fuse_file_info *fi) { int ret = 0; struct nfsfh *nfsfh; fi->fh = 0; ret = nfs_open(nfs, path, fi->flags, &nfsfh); if (ret < 0) { return ret; } fi->fh = (uint64_t)nfsfh; return ret; } static int fuse_nfs_release(const char *path, struct fuse_file_info *fi) { struct nfsfh *nfsfh = (struct nfsfh *)fi->fh; nfs_close(nfs, nfsfh); return 0; } static int fuse_nfs_read(const char *path, char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int ret = 0; struct nfsfh *nfsfh = (struct nfsfh *)fi->fh; ret = nfs_pread(nfs, nfsfh, offset, size, buf); return ret; } static int fuse_nfs_write(const char *path, const char *buf, size_t size, off_t offset, struct fuse_file_info *fi) { int ret = 0; struct nfsfh *nfsfh = (struct nfsfh *)fi->fh; ret = nfs_pwrite(nfs, nfsfh, offset, size, discard_const(buf)); return ret; } static int fuse_nfs_create(const char *path, mode_t mode, struct fuse_file_info *fi) { int ret = 0; struct nfsfh *nfsfh; ret = nfs_creat(nfs, path, mode, &nfsfh); if (ret < 0) { return ret; } fi->fh = (uint64_t)nfsfh; return ret; } static int fuse_nfs_utime(const char *path, struct utimbuf *times) { int ret = 0; ret = nfs_utime(nfs, path, times); if (ret < 0) { return ret; } return ret; } static int fuse_nfs_unlink(const char *path) { int ret = 0; ret = nfs_unlink(nfs, path); if (ret < 0) { return ret; } return ret; } static int fuse_nfs_rmdir(const char *path) { int ret = 0; ret = nfs_rmdir(nfs, path); if (ret < 0) { return ret; } return ret; } static int fuse_nfs_mkdir(const char *path, mode_t mode) { int ret = 0; ret = nfs_mkdir(nfs, path); if (ret < 0) { return ret; } ret = nfs_chmod(nfs, path, mode); if (ret < 0) { return ret; } return ret; } static struct fuse_operations nfs_oper = { .create = fuse_nfs_create, .getattr = fuse_nfs_getattr, .mkdir = fuse_nfs_mkdir, .open = fuse_nfs_open, .read = fuse_nfs_read, .readdir = fuse_nfs_readdir, .release = fuse_nfs_release, .rmdir = fuse_nfs_rmdir, .unlink = fuse_nfs_unlink, .utime = fuse_nfs_utime, .write = fuse_nfs_write, }; void print_usage(char *name) { printf("Usage: %s [-?|--help] [-n|--nfs-share=nfs-url] [-m|--mountpoint=mountpoint]\n", name); exit(0); } int main(int argc, char *argv[]) { int ret = 0; static struct option long_opts[] = { { "help", no_argument, 0, '?' }, { "nfs-share", required_argument, 0, 'n' }, { "mountpoint", required_argument, 0, 'm' }, { NULL, 0, 0, 0 } }; int c; int opt_idx = 0; char *url = NULL; char *mnt = NULL; char *server = NULL, *export = NULL, *strp; int fuse_nfs_argc = 6; char *fuse_nfs_argv[16] = { "fuse-nfs", "", "-oallow_other", "-odefault_permissions", "-omax_write=32768", "-s", NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, }; while ((c = getopt_long(argc, argv, "?hm:n:", long_opts, &opt_idx)) > 0) { switch (c) { case 'h': case '?': print_usage(argv[0]); return 0; case 'm': mnt = strdup(optarg); break; case 'n': url = strdup(optarg); break; } } if (url == NULL) { fprintf(stderr, "-n was not specified.\n"); print_usage(argv[0]); ret = 10; goto finished; } if (mnt == NULL) { fprintf(stderr, "-m was not specified.\n"); print_usage(argv[0]); ret = 10; goto finished; } if (strncmp(url, "nfs://", 6)) { fprintf(stderr, "Invalid URL specified.\n"); ret = 10; goto finished; } server = strdup(url + 6); if (server == NULL) { fprintf(stderr, "Failed to strdup server string\n"); ret = 10; goto finished; } if (server[0] == '/' || server[0] == '\0') { fprintf(stderr, "Invalid server string.\n"); ret = 10; goto finished; } strp = strchr(server, '/'); if (strp == NULL) { fprintf(stderr, "Invalid URL specified.\n"); ret = 10; goto finished; } export = strdup(strp); if (export == NULL) { fprintf(stderr, "Failed to strdup server string\n"); ret = 10; goto finished; } if (export[0] != '/') { fprintf(stderr, "Invalid export.\n"); ret = 10; goto finished; } *strp = 0; nfs = nfs_init_context(); if (nfs == NULL) { printf("failed to init context\n"); goto finished; } ret = nfs_mount(nfs, server, export); if (ret != 0) { printf("Failed to mount nfs share : %s\n", nfs_get_error(nfs)); goto finished; } fuse_nfs_argv[1] = mnt; return fuse_main(fuse_nfs_argc, fuse_nfs_argv, &nfs_oper, NULL); finished: if (nfs != NULL) { nfs_destroy_context(nfs); } free(server); free(export); free(url); free(mnt); return ret; } libnfs-libnfs-1.9.8/examples/ld_nfs.c000066400000000000000000000373011255745034100175220ustar00rootroot00000000000000/* Copyright (C) 2014 by Ronnie Sahlberg 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 . */ #define _GNU_SOURCE #include #include #include #include #include #include #include #include #include #include #include #define NFS_MAX_FD 255 static int debug = 0; #ifndef discard_const #define discard_const(ptr) ((void *)((intptr_t)(ptr))) #endif #define LD_NFS_DPRINTF(level, fmt, args...) \ do { \ if ((debug) >= level) { \ fprintf(stderr,"ld_nfs: "); \ fprintf(stderr, (fmt), ##args); \ fprintf(stderr,"\n"); \ } \ } while (0); struct nfs_fd_list { int is_nfs; struct nfs_context *nfs; struct nfsfh *fh; /* so we can reopen and emulate dup2() */ const char *path; int flags; mode_t mode; }; static struct nfs_fd_list nfs_fd_list[NFS_MAX_FD]; int (*real_open)(__const char *path, int flags, mode_t mode); int open(const char *path, int flags, mode_t mode) { if (!strncmp(path, "nfs:", 4)) { struct nfs_context *nfs; struct nfs_url *url; struct nfsfh *fh = NULL; int ret, fd; LD_NFS_DPRINTF(9, "open(%s, %x, %o)", path, flags, mode); nfs = nfs_init_context(); if (nfs == NULL) { LD_NFS_DPRINTF(1, "Failed to create context"); errno = ENOMEM; return -1; } url = nfs_parse_url_full(nfs, path); if (url == NULL) { LD_NFS_DPRINTF(1, "Failed to parse URL: %s\n", nfs_get_error(nfs)); nfs_destroy_context(nfs); errno = EINVAL; return -1; } if (nfs_mount(nfs, url->server, url->path) != 0) { LD_NFS_DPRINTF(1, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = EINVAL; return -1; } if (flags & O_CREAT) { if ((ret = nfs_creat(nfs, url->file, mode, &fh)) != 0) { LD_NFS_DPRINTF(1, "Failed to creat nfs file : " "%s\n", nfs_get_error(nfs)); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = -ret; return -1; } } else { if ((ret = nfs_open(nfs, url->file, flags, &fh)) != 0) { LD_NFS_DPRINTF(1, "Failed to open nfs file : " "%s\n", nfs_get_error(nfs)); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = -ret; return -1; } } fd = nfs_get_fd(nfs); if (fd >= NFS_MAX_FD) { LD_NFS_DPRINTF(1, "Too many files open"); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = ENFILE; return -1; } nfs_fd_list[fd].is_nfs = 1; nfs_fd_list[fd].nfs = nfs; nfs_fd_list[fd].fh = fh; nfs_fd_list[fd].path = strdup(path); nfs_fd_list[fd].flags = flags; nfs_fd_list[fd].mode = mode; nfs_destroy_url(url); LD_NFS_DPRINTF(9, "open(%s) == %d", path, fd); return fd; } return real_open(path, flags, mode); } int open64(const char *path, int flags, mode_t mode) { return open(path, flags | O_LARGEFILE, mode); } int (*real_close)(int fd); int close(int fd) { if (nfs_fd_list[fd].is_nfs == 1) { int i; LD_NFS_DPRINTF(9, "close(%d)", fd); nfs_fd_list[fd].is_nfs = 0; nfs_close(nfs_fd_list[fd].nfs, nfs_fd_list[fd].fh); nfs_fd_list[fd].fh = NULL; nfs_destroy_context(nfs_fd_list[fd].nfs); nfs_fd_list[fd].nfs = NULL; free(discard_const(nfs_fd_list[fd].path)); nfs_fd_list[fd].path = NULL; return 0; } return real_close(fd); } ssize_t (*real_read)(int fd, void *buf, size_t count); ssize_t read(int fd, void *buf, size_t count) { if (nfs_fd_list[fd].is_nfs == 1) { int ret; LD_NFS_DPRINTF(9, "read(fd:%d count:%d)", fd, (int)count); if ((ret = nfs_read(nfs_fd_list[fd].nfs, nfs_fd_list[fd].fh, count, buf)) < 0) { errno = -ret; return -1; } return ret; } return real_read(fd, buf, count); } ssize_t (*real_pread)(int fd, void *buf, size_t count, off_t offset); ssize_t pread(int fd, void *buf, size_t count, off_t offset) { if (nfs_fd_list[fd].is_nfs == 1) { int ret; LD_NFS_DPRINTF(9, "pread(fd:%d offset:%d count:%d)", fd, (int)offset, (int)count); if ((ret = nfs_pread(nfs_fd_list[fd].nfs, nfs_fd_list[fd].fh, offset, count, buf)) < 0) { errno = -ret; return -1; } return ret; } return real_pread(fd, buf, count, offset); } ssize_t (*real_write)(int fd, const void *buf, size_t count); ssize_t write(int fd, const void *buf, size_t count) { if (nfs_fd_list[fd].is_nfs == 1) { int ret; LD_NFS_DPRINTF(9, "write(fd:%d count:%d)", fd, (int)count); if ((ret = nfs_write(nfs_fd_list[fd].nfs, nfs_fd_list[fd].fh, count, (char *)discard_const(buf))) < 0) { errno = -ret; return -1; } return ret; } return real_write(fd, buf, count); } ssize_t (*real_pwrite)(int fd, const void *buf, size_t count, off_t offset); ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset) { if (nfs_fd_list[fd].is_nfs == 1) { int ret; LD_NFS_DPRINTF(9, "pwrite(fd:%d offset:%d count:%d)", fd, (int)offset, (int)count); if ((ret = nfs_pwrite(nfs_fd_list[fd].nfs, nfs_fd_list[fd].fh, offset, count, (char *)discard_const(buf))) < 0) { errno = -ret; return -1; } return ret; } return real_pwrite(fd, buf, count, offset); } int (*real_dup2)(int oldfd, int newfd); int dup2(int oldfd, int newfd) { close(newfd); if (nfs_fd_list[oldfd].is_nfs == 1) { struct nfs_context *nfs; struct nfs_url *url; struct nfsfh *fh = NULL; int ret, fd; LD_NFS_DPRINTF(9, "dup2(%s:%d, %d)", nfs_fd_list[oldfd].path, oldfd, newfd); nfs = nfs_init_context(); if (nfs == NULL) { LD_NFS_DPRINTF(1, "Failed to create context"); errno = ENOMEM; return -1; } url = nfs_parse_url_full(nfs, nfs_fd_list[oldfd].path); if (url == NULL) { LD_NFS_DPRINTF(1, "Failed to parse URL: %s\n", nfs_get_error(nfs)); nfs_destroy_context(nfs); errno = EINVAL; return -1; } if (nfs_mount(nfs, url->server, url->path) != 0) { LD_NFS_DPRINTF(1, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = EINVAL; return -1; } if ((ret = nfs_open(nfs, url->file, nfs_fd_list[oldfd].mode, &fh)) != 0) { LD_NFS_DPRINTF(1, "Failed to open nfs file : %s\n", nfs_get_error(nfs)); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = -ret; return -1; } /* We could actually end on the right descriptor by chance */ if (nfs_get_fd(nfs) != newfd) { if (real_dup2(nfs_get_fd(nfs), newfd) < 0) { LD_NFS_DPRINTF(1, "Failed to dup2 file : %d", errno); return -1; } close(rpc_get_fd(nfs_get_rpc_context(nfs))); rpc_set_fd(nfs_get_rpc_context(nfs), newfd); } fd = nfs_get_fd(nfs); if (fd >= NFS_MAX_FD) { LD_NFS_DPRINTF(1, "Too many files open"); nfs_destroy_url(url); nfs_destroy_context(nfs); errno = ENFILE; return -1; } nfs_fd_list[fd].is_nfs = 1; nfs_fd_list[fd].nfs = nfs; nfs_fd_list[fd].fh = fh; nfs_fd_list[fd].path = strdup(nfs_fd_list[oldfd].path); nfs_fd_list[fd].flags = nfs_fd_list[oldfd].flags; nfs_fd_list[fd].mode = nfs_fd_list[oldfd].mode; nfs_destroy_url(url); LD_NFS_DPRINTF(9, "dup2(%s) successful", nfs_fd_list[oldfd].path); return fd; } return real_dup2(oldfd, newfd); } int (*real_xstat)(int ver, __const char *path, struct stat *buf); int __xstat(int ver, const char *path, struct stat *buf) { if (!strncmp(path, "nfs:", 4)) { int fd, ret; LD_NFS_DPRINTF(9, "__xstat(%s)", path); fd = open(path, 0, 0); if (fd == -1) { return fd; } ret = __fxstat(ver, fd, buf); close(fd); return ret; } return real_xstat(ver, path, buf); } int (*real_xstat64)(int ver, __const char *path, struct stat64 *buf); int __xstat64(int ver, const char *path, struct stat64 *buf) { if (!strncmp(path, "nfs:", 4)) { int fd, ret; LD_NFS_DPRINTF(9, "__xstat64(%s)", path); fd = open(path, 0, 0); if (fd == -1) { return fd; } ret = __fxstat64(ver, fd, buf); close(fd); return ret; } return real_xstat64(ver, path, buf); } int (*real_lxstat)(int ver, __const char *path, struct stat *buf); int __lxstat(int ver, const char *path, struct stat *buf) { if (!strncmp(path, "nfs:", 4)) { int fd, ret; LD_NFS_DPRINTF(9, "__lxstat(%s)", path); fd = open(path, 0, 0); if (fd == -1) { return fd; } ret = __fxstat(ver, fd, buf); close(fd); return ret; } return real_lxstat(ver, path, buf); } int (*real_lxstat64)(int ver, __const char *path, struct stat64 *buf); int __lxstat64(int ver, const char *path, struct stat64 *buf) { if (!strncmp(path, "nfs:", 4)) { int fd, ret; LD_NFS_DPRINTF(9, "__lxstat64(%s)", path); fd = open(path, 0, 0); if (fd == -1) { return fd; } ret = __fxstat64(ver, fd, buf); close(fd); return ret; } return real_lxstat64(ver, path, buf); } int (*real_fxstat)(int ver, int fd, struct stat *buf); int __fxstat(int ver, int fd, struct stat *buf) { if (nfs_fd_list[fd].is_nfs == 1) { int ret; struct nfs_stat_64 st64; LD_NFS_DPRINTF(9, "__fxstat(%d)", fd); if ((ret = nfs_fstat64(nfs_fd_list[fd].nfs, nfs_fd_list[fd].fh, (void *)&st64)) < 0) { errno = -ret; return -1; } buf->st_dev = st64.nfs_dev; buf->st_ino = st64.nfs_ino; buf->st_mode = st64.nfs_mode; buf->st_nlink = st64.nfs_nlink; buf->st_uid = st64.nfs_uid; buf->st_gid = st64.nfs_gid; buf->st_rdev = st64.nfs_rdev; buf->st_size = st64.nfs_size; buf->st_blksize = st64.nfs_blksize; buf->st_blocks = st64.nfs_blocks; buf->st_atim.tv_sec = st64.nfs_atime; buf->st_atim.tv_usec = st64.nfs_atime_nsec / 1000; buf->st_mtim.tv_sec = st64.nfs_mtime; buf->st_mtim.tv_usec = st64.nfs_mtime_nsec / 1000; buf->st_ctim.tv_sec = st64.nfs_ctime; buf->st_ctim.tv_usec = st64.nfs_ctime_nsec / 1000; LD_NFS_DPRINTF(9, "__fxstat(%d) success", fd); return ret; } return real_fxstat(ver, fd, buf); } int (*real_fxstat64)(int ver, int fd, struct stat64 *buf); int __fxstat64(int ver, int fd, struct stat64 *buf) { if (nfs_fd_list[fd].is_nfs == 1) { int ret; struct nfs_stat_64 st64; LD_NFS_DPRINTF(9, "__fxstat64(%d)", fd); if ((ret = nfs_fstat64(nfs_fd_list[fd].nfs, nfs_fd_list[fd].fh, (void *)&st64)) < 0) { errno = -ret; return -1; } buf->st_dev = st64.nfs_dev; buf->st_ino = st64.nfs_ino; buf->st_mode = st64.nfs_mode; buf->st_nlink = st64.nfs_nlink; buf->st_uid = st64.nfs_uid; buf->st_gid = st64.nfs_gid; buf->st_rdev = st64.nfs_rdev; buf->st_size = st64.nfs_size; buf->st_blksize = st64.nfs_blksize; buf->st_blocks = st64.nfs_blocks; buf->st_atim.tv_sec = st64.nfs_atime; buf->st_atim.tv_usec = st64.nfs_atime_nsec / 1000; buf->st_mtim.tv_sec = st64.nfs_mtime; buf->st_mtim.tv_usec = st64.nfs_mtime_nsec / 1000; buf->st_ctim.tv_sec = st64.nfs_ctime; buf->st_ctim.tv_usec = st64.nfs_ctime_nsec / 1000; LD_NFS_DPRINTF(9, "__fxstat64(%d) success", fd); return ret; } return real_fxstat64(ver, fd, buf); } int (*real_fallocate)(int fd, int mode, off_t offset, off_t len); int fallocate(int fd, int mode, off_t offset, off_t len) { if (nfs_fd_list[fd].is_nfs == 1) { LD_NFS_DPRINTF(9, "fallocate(%d)", fd); errno = EOPNOTSUPP; return -1; } return real_fallocate(fd, mode, offset, len); } int (*real_ftruncate)(int fd, off_t len); int ftruncate(int fd, off_t len) { if (nfs_fd_list[fd].is_nfs == 1) { int ret; LD_NFS_DPRINTF(9, "ftruncate(%d, %d)", fd, (int)len); if ((ret = nfs_ftruncate(nfs_fd_list[fd].nfs, nfs_fd_list[fd].fh, len)) < 0) { errno = -ret; return -1; } return 0; } return real_ftruncate(fd, len); } int (*real_truncate)(const char *path, off_t len); int truncate(const char *path, off_t len) { if (!strncmp(path, "nfs:", 4)) { int fd, ret; LD_NFS_DPRINTF(9, "truncate(%s, %d)", path, (int)len); fd = open(path, 0, 0); if (fd == -1) { return fd; } ret = ftruncate(fd, len); close(fd); return ret; } return real_truncate(path, len); } int (*real_fchmod)(int fd, mode_t mode); int fchmod(int fd, mode_t mode) { if (nfs_fd_list[fd].is_nfs == 1) { int ret; LD_NFS_DPRINTF(9, "fchmod(%d, %o)", fd, (int)mode); if ((ret = nfs_fchmod(nfs_fd_list[fd].nfs, nfs_fd_list[fd].fh, mode)) < 0) { errno = -ret; return -1; } return 0; } return real_fchmod(fd, mode); } int (*real_chmod)(const char *path, mode_t mode); int chmod(const char *path, mode_t mode) { if (!strncmp(path, "nfs:", 4)) { int fd, ret; LD_NFS_DPRINTF(9, "chmod(%s, %o)", path, (int)mode); fd = open(path, 0, 0); if (fd == -1) { return fd; } ret = fchmod(fd, mode); close(fd); return ret; } return real_chmod(path, mode); } static void __attribute__((constructor)) _init(void) { int i; if (getenv("LD_NFS_DEBUG") != NULL) { debug = atoi(getenv("LD_NFS_DEBUG")); } real_open = dlsym(RTLD_NEXT, "open"); if (real_open == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(open)"); exit(10); } real_close = dlsym(RTLD_NEXT, "close"); if (real_close == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(close)"); exit(10); } real_read = dlsym(RTLD_NEXT, "read"); if (real_read == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(read)"); exit(10); } real_pread = dlsym(RTLD_NEXT, "pread"); if (real_pread == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(pread)"); exit(10); } real_write = dlsym(RTLD_NEXT, "write"); if (real_write == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(write)"); exit(10); } real_pwrite = dlsym(RTLD_NEXT, "pwrite"); if (real_pwrite == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(pwrite)"); exit(10); } real_xstat = dlsym(RTLD_NEXT, "__xstat"); if (real_xstat == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(__xstat)"); exit(10); } real_xstat64 = dlsym(RTLD_NEXT, "__xstat64"); if (real_xstat64 == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(__xstat64)"); } real_lxstat = dlsym(RTLD_NEXT, "__lxstat"); if (real_lxstat == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(__lxstat)"); exit(10); } real_lxstat64 = dlsym(RTLD_NEXT, "__lxstat64"); if (real_lxstat64 == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(_lxstat64)"); exit(10); } real_fxstat = dlsym(RTLD_NEXT, "__fxstat"); if (real_fxstat == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(__fxstat)"); exit(10); } real_fxstat64 = dlsym(RTLD_NEXT, "__fxstat64"); if (real_fxstat64 == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(__fxstat64)"); exit(10); } real_fallocate = dlsym(RTLD_NEXT, "fallocate"); if (real_fallocate == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(fallocate)"); exit(10); } real_dup2 = dlsym(RTLD_NEXT, "dup2"); if (real_dup2 == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(dup2)"); exit(10); } real_truncate = dlsym(RTLD_NEXT, "truncate"); if (real_truncate == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(truncate)"); exit(10); } real_ftruncate = dlsym(RTLD_NEXT, "ftruncate"); if (real_ftruncate == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(ftruncate)"); exit(10); } real_chmod = dlsym(RTLD_NEXT, "chmod"); if (real_chmod == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(chmod)"); exit(10); } real_fchmod = dlsym(RTLD_NEXT, "fchmod"); if (real_fchmod == NULL) { LD_NFS_DPRINTF(0, "Failed to dlsym(fchmod)"); exit(10); } } libnfs-libnfs-1.9.8/examples/nfs-io.c000066400000000000000000000075221255745034100174520ustar00rootroot00000000000000/* Copyright (C) by Peter Lieven 2013 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 . */ #define _FILE_OFFSET_BITS 64 #define _GNU_SOURCE #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #pragma comment(lib, "ws2_32.lib") WSADATA wsaData; #define PRId64 "ll" #else #include #include #include #include #ifndef AROS #include #endif #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" void print_usage(void) { fprintf(stderr, "Usage: nfs-io [-?|--help|--usage] [stat|creat|unlink|mkdir|rmdir] \n"); } int main(int argc, char *argv[]) { int ret = 1; struct nfs_context *nfs = NULL; struct nfsfh *nfsfh = NULL; struct nfs_url *url = NULL; #ifdef WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { printf("Failed to start Winsock2\n"); exit(10); } #endif #ifdef AROS aros_init_socket(); #endif if (argc < 3) { fprintf(stderr, "No URL specified.\n"); goto finished; } nfs = nfs_init_context(); if (nfs == NULL) { printf("failed to init context\n"); goto finished; } url = nfs_parse_url_full(nfs, argv[argc - 1]); if (url == NULL) { fprintf(stderr, "%s\n", nfs_get_error(nfs)); goto finished; } if (nfs_mount(nfs, url->server, url->path) != 0) { fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); goto finished; } if (!strncmp(argv[1], "creat", 5)) { ret = nfs_creat(nfs, url->file, 0600, &nfsfh); } else if (!strncmp(argv[1], "unlink", 6)) { ret = nfs_unlink(nfs, url->file); } else if (!strncmp(argv[1], "mkdir", 5)) { ret = nfs_mkdir(nfs, url->file); } else if (!strncmp(argv[1], "rmdir", 5)) { ret = nfs_rmdir(nfs, url->file); } else if (!strncmp(argv[1], "stat", 4)) { struct nfs_stat_64 st; ret = nfs_stat64(nfs, url->file, &st); if (!ret) { switch (st.nfs_mode & S_IFMT) { #ifndef WIN32 case S_IFLNK: printf("l"); break; #endif case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; case S_IFCHR: printf("c"); break; case S_IFBLK: printf("b"); break; } printf("%c%c%c", "-r"[!!(st.nfs_mode & S_IRUSR)], "-w"[!!(st.nfs_mode & S_IWUSR)], "-x"[!!(st.nfs_mode & S_IXUSR)] ); printf("%c%c%c", "-r"[!!(st.nfs_mode & S_IRGRP)], "-w"[!!(st.nfs_mode & S_IWGRP)], "-x"[!!(st.nfs_mode & S_IXGRP)] ); printf("%c%c%c", "-r"[!!(st.nfs_mode & S_IROTH)], "-w"[!!(st.nfs_mode & S_IWOTH)], "-x"[!!(st.nfs_mode & S_IXOTH)] ); printf(" %2d", (int)st.nfs_nlink); printf(" %5d", (int)st.nfs_uid); printf(" %5d", (int)st.nfs_gid); printf(" %12" PRId64, st.nfs_size); printf("\n"); } } else { goto finished; } if (ret) { fprintf(stderr, "ERROR: %s\n", nfs_get_error(nfs)); } finished: if (ret > 0) { print_usage(); } nfs_destroy_url(url); if (nfs != NULL) { if (nfsfh) { nfs_close(nfs, nfsfh); } nfs_destroy_context(nfs); } return !!ret; } libnfs-libnfs-1.9.8/examples/nfsclient-async.c000066400000000000000000000161641255745034100213610ustar00rootroot00000000000000/* Copyright (C) by Ronnie Sahlberg 2010 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 . */ /* Example program using the highlevel async interface. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WIN32 #include "win32_compat.h" #else #include #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #define SERVER "10.1.1.27" #define EXPORT "/VIRTUAL" #define NFSFILE "/BOOKS/Classics/Dracula.djvu" #define NFSDIR "/BOOKS/Classics/" #include #include #include #include #include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" struct rpc_context *mount_context; struct client { char *server; char *export; uint32_t mount_port; struct nfsfh *nfsfh; int is_finished; }; void mount_export_cb(struct rpc_context *mount_context, int status, void *data, void *private_data) { struct client *client = private_data; exports export = *(exports *)data; if (status < 0) { printf("MOUNT/EXPORT failed with \"%s\"\n", rpc_get_error(mount_context)); exit(10); } printf("Got exports list from server %s\n", client->server); while (export != NULL) { printf("Export: %s\n", export->ex_dir); export = export->ex_next; } mount_context = NULL; client->is_finished = 1; } void nfs_opendir_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct client *client = private_data; struct nfsdir *nfsdir = data; struct nfsdirent *nfsdirent; if (status < 0) { printf("opendir failed with \"%s\"\n", (char *)data); exit(10); } printf("opendir successful\n"); while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { printf("Inode:%d Name:%s\n", (int)nfsdirent->inode, nfsdirent->name); } nfs_closedir(nfs, nfsdir); mount_context = rpc_init_context(); if (mount_getexports_async(mount_context, client->server, mount_export_cb, client) != 0) { printf("Failed to start MOUNT/EXPORT\n"); exit(10); } } void nfs_close_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct client *client = private_data; if (status < 0) { printf("close failed with \"%s\"\n", (char *)data); exit(10); } printf("close successful\n"); printf("call opendir(%s)\n", NFSDIR); if (nfs_opendir_async(nfs, NFSDIR, nfs_opendir_cb, client) != 0) { printf("Failed to start async nfs close\n"); exit(10); } } void nfs_fstat64_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct client *client = private_data; struct nfs_stat_64 *st; if (status < 0) { printf("fstat call failed with \"%s\"\n", (char *)data); exit(10); } printf("Got reply from server for fstat(%s).\n", NFSFILE); st = (struct nfs_stat_64 *)data; printf("Mode %04o\n", (int)st->nfs_mode); printf("Size %d\n", (int)st->nfs_size); printf("Inode %04o\n", (int)st->nfs_ino); printf("Close file\n"); if (nfs_close_async(nfs, client->nfsfh, nfs_close_cb, client) != 0) { printf("Failed to start async nfs close\n"); exit(10); } } void nfs_read_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct client *client = private_data; char *read_data; int i; if (status < 0) { printf("read failed with \"%s\"\n", (char *)data); exit(10); } printf("read successful with %d bytes of data\n", status); read_data = data; for (i=0;i<16;i++) { printf("%02x ", read_data[i]&0xff); } printf("\n"); printf("Fstat file :%s\n", NFSFILE); if (nfs_fstat64_async(nfs, client->nfsfh, nfs_fstat64_cb, client) != 0) { printf("Failed to start async nfs fstat\n"); exit(10); } } void nfs_open_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct client *client = private_data; struct nfsfh *nfsfh; if (status < 0) { printf("open call failed with \"%s\"\n", (char *)data); exit(10); } nfsfh = data; client->nfsfh = nfsfh; printf("Got reply from server for open(%s). Handle:%p\n", NFSFILE, data); printf("Read first 64 bytes\n"); if (nfs_pread_async(nfs, nfsfh, 0, 64, nfs_read_cb, client) != 0) { printf("Failed to start async nfs open\n"); exit(10); } } void nfs_stat64_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct client *client = private_data; struct nfs_stat_64 *st; if (status < 0) { printf("stat call failed with \"%s\"\n", (char *)data); exit(10); } printf("Got reply from server for stat(%s).\n", NFSFILE); st = (struct nfs_stat_64 *)data; printf("Mode %04o\n", (unsigned int) st->nfs_mode); printf("Size %d\n", (int)st->nfs_size); printf("Inode %04o\n", (int)st->nfs_ino); printf("Open file for reading :%s\n", NFSFILE); if (nfs_open_async(nfs, NFSFILE, O_RDONLY, nfs_open_cb, client) != 0) { printf("Failed to start async nfs open\n"); exit(10); } } void nfs_mount_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct client *client = private_data; if (status < 0) { printf("mount/mnt call failed with \"%s\"\n", (char *)data); exit(10); } printf("Got reply from server for MOUNT/MNT procedure.\n"); printf("Stat file :%s\n", NFSFILE); if (nfs_stat64_async(nfs, NFSFILE, nfs_stat64_cb, client) != 0) { printf("Failed to start async nfs stat\n"); exit(10); } } int main(int argc _U_, char *argv[] _U_) { struct nfs_context *nfs; int ret; struct client client; struct pollfd pfds[2]; /* nfs:0 mount:1 */ client.server = SERVER; client.export = EXPORT; client.is_finished = 0; nfs = nfs_init_context(); if (nfs == NULL) { printf("failed to init context\n"); exit(10); } ret = nfs_mount_async(nfs, client.server, client.export, nfs_mount_cb, &client); if (ret != 0) { printf("Failed to start async nfs mount\n"); exit(10); } for (;;) { int num_fds; pfds[0].fd = nfs_get_fd(nfs); pfds[0].events = nfs_which_events(nfs); num_fds = 1; if (mount_context != 0 && rpc_get_fd(mount_context) != -1) { pfds[1].fd = rpc_get_fd(mount_context); pfds[1].events = rpc_which_events(mount_context); num_fds = 2; } if (poll(&pfds[0], 2, -1) < 0) { printf("Poll failed"); exit(10); } if (mount_context != NULL) { if (rpc_service(mount_context, pfds[1].revents) < 0) { printf("rpc_service failed\n"); break; } } if (nfs_service(nfs, pfds[0].revents) < 0) { printf("nfs_service failed\n"); break; } if (client.is_finished) { break; } } nfs_destroy_context(nfs); if (mount_context != NULL) { rpc_destroy_context(mount_context); mount_context = NULL; } printf("nfsclient finished\n"); return 0; } libnfs-libnfs-1.9.8/examples/nfsclient-bcast.c000066400000000000000000000131051255745034100213300ustar00rootroot00000000000000/* Copyright (C) by Ronnie Sahlberg 2011 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 . */ /* Example program using the lowlevel raw broadcast interface. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WIN32 #include "win32_compat.h" #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #ifdef HAVE_SYS_TIME_H #include #endif #ifdef HAVE_NET_IF_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" #include "libnfs-raw-mount.h" #include "libnfs-raw-portmap.h" struct nfs_list_data { int status; struct nfs_server_list *srvrs; }; void free_nfs_srvr_list(struct nfs_server_list *srv) { while (srv != NULL) { struct nfs_server_list *next = srv->next; free(srv->addr); free(srv); srv = next; } } void pm_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) { struct nfs_list_data *srv_data = private_data; struct sockaddr *sin; char hostdd[16]; struct nfs_server_list *srvr; if (status == RPC_STATUS_CANCEL) { return; } if (status != 0) { srv_data->status = -1; return; } sin = rpc_get_recv_sockaddr(rpc); if (sin == NULL) { rpc_set_error(rpc, "failed to get sockaddr in CALLIT callback"); srv_data->status = -1; return; } if (getnameinfo(sin, sizeof(struct sockaddr_in), &hostdd[0], sizeof(hostdd), NULL, 0, NI_NUMERICHOST) < 0) { rpc_set_error(rpc, "getnameinfo failed in CALLIT callback"); srv_data->status = -1; return; } srvr = malloc(sizeof(struct nfs_server_list)); if (srvr == NULL) { rpc_set_error(rpc, "Malloc failed when allocating server structure"); srv_data->status = -1; return; } srvr->addr = strdup(hostdd); if (srvr->addr == NULL) { rpc_set_error(rpc, "Strdup failed when allocating server structure"); free(srvr); srv_data->status = -1; return; } srvr->next = srv_data->srvrs; srv_data->srvrs = srvr; } int main(int argc _U_, char *argv[] _U_) { struct rpc_context *rpc; struct pollfd pfd; struct ifconf ifc; int size; struct timeval tv_start, tv_current; struct nfs_list_data data = {0, NULL}; struct nfs_server_list *srvr; char *ptr; rpc = rpc_init_udp_context(); if (rpc == NULL) { printf("failed to init context\n"); exit(10); } if (rpc_bind_udp(rpc, "0.0.0.0", 0) < 0) { printf("failed to bind to udp %s\n", rpc_get_error(rpc)); exit(10); } /* get list of all interfaces */ size = sizeof(struct ifreq); ifc.ifc_buf = NULL; ifc.ifc_len = size; while(ifc.ifc_len > (size - sizeof(struct ifreq))) { size *= 2; free(ifc.ifc_buf); ifc.ifc_len = size; ifc.ifc_buf = malloc(size); memset(ifc.ifc_buf, 0, size); if (ioctl(rpc_get_fd(rpc), SIOCGIFCONF, (caddr_t)&ifc) < 0) { printf("ioctl SIOCGIFCONF failed\n"); exit(10); } } for (ptr =(char *)ifc.ifc_buf; ptr < ((char *)ifc.ifc_buf) + ifc.ifc_len; ) { struct ifreq *ifr; char bcdd[16]; ifr = (struct ifreq *)ptr; #ifdef HAVE_SOCKADDR_LEN if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)) { ptr += sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len; } else { ptr += sizeof(ifr->ifr_name) + sizeof(struct sockaddr); } #else ptr += sizeof(struct ifreq); #endif if (ifr->ifr_addr.sa_family != AF_INET) { continue; } if (ioctl(rpc_get_fd(rpc), SIOCGIFFLAGS, ifr) < 0) { printf("ioctl DRBADDR failed\n"); exit(10); } if (!(ifr->ifr_flags & IFF_UP)) { continue; } if (ifr->ifr_flags & IFF_LOOPBACK) { continue; } if (!(ifr->ifr_flags & IFF_BROADCAST)) { continue; } if (ioctl(rpc_get_fd(rpc), SIOCGIFBRDADDR, ifr) < 0) { continue; } if (getnameinfo(&ifr->ifr_broadaddr, sizeof(struct sockaddr_in), &bcdd[0], sizeof(bcdd), NULL, 0, NI_NUMERICHOST) < 0) { continue; } if (rpc_set_udp_destination(rpc, bcdd, 111, 1) < 0) { printf("failed to set udp destination %s\n", rpc_get_error(rpc)); exit(10); } if (rpc_pmap2_callit_async(rpc, MOUNT_PROGRAM, 2, 0, NULL, 0, pm_cb, &data) < 0) { printf("Failed to set up callit function\n"); exit(10); } } free(ifc.ifc_buf); gettimeofday(&tv_start, NULL); for(;;) { int mpt; pfd.fd = rpc_get_fd(rpc); pfd.events = rpc_which_events(rpc); gettimeofday(&tv_current, NULL); mpt = 1000 - (tv_current.tv_sec *1000 + tv_current.tv_usec / 1000) + (tv_start.tv_sec *1000 + tv_start.tv_usec / 1000); if (poll(&pfd, 1, mpt) < 0) { printf("Poll failed"); exit(10); } if (pfd.revents == 0) { break; } if (rpc_service(rpc, pfd.revents) < 0) { printf("rpc_service failed with %s\n", rpc_get_error(rpc)); break; } } for (srvr=data.srvrs; srvr; srvr = srvr->next) { printf("NFS SERVER @ %s\n", srvr->addr); } free_nfs_srvr_list(data.srvrs); rpc_destroy_context(rpc); rpc=NULL; return 0; } libnfs-libnfs-1.9.8/examples/nfsclient-listservers.c000066400000000000000000000023621255745034100226240ustar00rootroot00000000000000/* Copyright (C) by Ronnie Sahlberg 2011 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 . */ /* Example program showing sync interface to probe for all local servers */ #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #endif #include #include #include "libnfs.h" int main(int argc _U_, char *argv[] _U_) { struct nfs_server_list *srvrs; struct nfs_server_list *srv; #ifdef AROS aros_init_socket(); #endif srvrs = nfs_find_local_servers(); for (srv=srvrs; srv; srv = srv->next) { printf("NFS SERVER @ %s\n", srv->addr); } free_nfs_srvr_list(srvrs); return 0; } libnfs-libnfs-1.9.8/examples/nfsclient-raw.c000066400000000000000000000322701255745034100210310ustar00rootroot00000000000000/* Copyright (C) by Ronnie Sahlberg 2010 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 . */ /* Example program using the lowlevel raw interface. * This allow accurate control of the exact commands that are being used. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WIN32 #include "win32_compat.h" #endif #define SERVER "10.1.1.27" #define EXPORT "/shared" #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #include #include #include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" #include "libnfs-raw-nfs.h" #include "libnfs-raw-portmap.h" #include "libnfs-raw-rquota.h" struct client { char *server; char *export; uint32_t mount_port; uint32_t rquota_port; int is_finished; struct nfs_fh3 rootfh; }; void rquota_getquota_cb(struct rpc_context *rpc _U_, int status, void *data, void *private_data) { struct client *client = private_data; // GETQUOTA1res *res = data; if (status == RPC_STATUS_ERROR) { printf("rquota/getquota call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("rquota/getquota call to server %s failed, status:%d\n", client->server, status); exit(10); } printf("rquota responded ok\n"); client->is_finished = 1; } void rquota_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) { struct client *client = private_data; if (status != RPC_STATUS_SUCCESS) { printf("connection to RPC.RQUOTAD on server %s failed\n", client->server); exit(10); } printf("Connected to RPC.RQUOTAD on %s:%d\n", client->server, client->rquota_port); printf("Send GETQUOTA request for uid 100\n"); if (rpc_rquota1_getquota_async(rpc, rquota_getquota_cb, EXPORT, 100, client) != 0) { printf("Failed to send getquota request\n"); exit(10); } } void acl_getacl_cb(struct rpc_context *rpc _U_, int status, void *data, void *private_data) { struct client *client = private_data; GETACL3res *res = data; printf("Got NFSACL/GETACL reply\n"); if (status == RPC_STATUS_SUCCESS) { printf("Got an ACL : ACL status:%d\n", res->status); if (res->status == NFS3_OK) { int i; printf("ACL MASK 0x%08x\n", res->GETACL3res_u.resok.mask); printf("NUM ACE %d\n", res->GETACL3res_u.resok.ace_count); for (i=0; iGETACL3res_u.resok.ace.ace_len; i++) { printf("Type:0x%08x\n", res->GETACL3res_u.resok.ace.ace_val[i].type); printf("ID:%d\n", res->GETACL3res_u.resok.ace.ace_val[i].id); printf("Perm:0x%08x\n", res->GETACL3res_u.resok.ace.ace_val[i].perm); } } } printf("Disconnect socket from nfs server\n"); if (rpc_disconnect(rpc, "normal disconnect") != 0) { printf("Failed to disconnect socket to nfs\n"); exit(10); } printf("Connect to RPC.RQUOTAD on %s:%d\n", client->server, client->rquota_port); if (rpc_connect_async(rpc, client->server, client->rquota_port, rquota_connect_cb, client) != 0) { printf("Failed to start connection\n"); exit(10); } } void acl_null_cb(struct rpc_context *rpc _U_, int status, void *data, void *private_data) { struct client *client = private_data; GETACL3args args; printf("Got NFSACL/NULL reply\n"); printf("Get ACL for root handle\n"); args.dir = client->rootfh; args.mask = NFSACL_MASK_ACL_ENTRY|NFSACL_MASK_ACL_COUNT|NFSACL_MASK_ACL_DEFAULT_ENTRY|NFSACL_MASK_ACL_DEFAULT_COUNT; if (rpc_nfsacl_getacl_async(rpc, acl_getacl_cb, &args, client) != 0) { printf("Failed to send getacl request\n"); exit(10); } } void nfs_fsinfo_cb(struct rpc_context *rpc _U_, int status, void *data, void *private_data) { struct client *client = private_data; FSINFO3res *res = data; if (status == RPC_STATUS_ERROR) { printf("nfs/fsinfo call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("nfs/fsinfo call to server %s failed, status:%d\n", client->server, status); exit(10); } printf("Got reply from server for NFS/FSINFO procedure.\n"); printf("Read Max:%d\n", (int)res->FSINFO3res_u.resok.rtmax); printf("Write Max:%d\n", (int)res->FSINFO3res_u.resok.wtmax); printf("Send NFSACL/NULL request\n"); if (rpc_nfsacl_null_async(rpc, acl_null_cb, client) != 0) { printf("Failed to send acl/null request\n"); exit(10); } } void nfs_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) { struct client *client = private_data; struct FSINFO3args args; if (status != RPC_STATUS_SUCCESS) { printf("connection to RPC.MOUNTD on server %s failed\n", client->server); exit(10); } printf("Connected to RPC.NFSD on %s:%d\n", client->server, client->mount_port); printf("Send FSINFO request\n"); args.fsroot = client->rootfh; if (rpc_nfs3_fsinfo_async(rpc, nfs_fsinfo_cb, &args, client) != 0) { printf("Failed to send fsinfo request\n"); exit(10); } } void mount_mnt_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; mountres3 *mnt = data; if (status == RPC_STATUS_ERROR) { printf("mount/mnt call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("mount/mnt call to server %s failed, status:%d\n", client->server, status); exit(10); } printf("Got reply from server for MOUNT/MNT procedure.\n"); client->rootfh.data.data_len = mnt->mountres3_u.mountinfo.fhandle.fhandle3_len; client->rootfh.data.data_val = malloc(client->rootfh.data.data_len); memcpy(client->rootfh.data.data_val, mnt->mountres3_u.mountinfo.fhandle.fhandle3_val, client->rootfh.data.data_len); printf("Disconnect socket from mountd server\n"); if (rpc_disconnect(rpc, "normal disconnect") != 0) { printf("Failed to disconnect socket to mountd\n"); exit(10); } printf("Connect to RPC.NFSD on %s:%d\n", client->server, 2049); if (rpc_connect_async(rpc, client->server, 2049, nfs_connect_cb, client) != 0) { printf("Failed to start connection\n"); exit(10); } } void mount_export_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; exports export = *(exports *)data; if (status == RPC_STATUS_ERROR) { printf("mount null call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("mount null call to server %s failed, status:%d\n", client->server, status); exit(10); } printf("Got reply from server for MOUNT/EXPORT procedure.\n"); while (export != NULL) { printf("Export: %s\n", export->ex_dir); export = export->ex_next; } printf("Send MOUNT/MNT command for %s\n", client->export); if (rpc_mount_mnt_async(rpc, mount_mnt_cb, client->export, client) != 0) { printf("Failed to send mnt request\n"); exit(10); } } void mount_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; if (status == RPC_STATUS_ERROR) { printf("mount null call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("mount null call to server %s failed, status:%d\n", client->server, status); exit(10); } printf("Got reply from server for MOUNT/NULL procedure.\n"); printf("Send MOUNT/EXPORT command\n"); if (rpc_mount_export_async(rpc, mount_export_cb, client) != 0) { printf("Failed to send export request\n"); exit(10); } } void mount_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) { struct client *client = private_data; if (status != RPC_STATUS_SUCCESS) { printf("connection to RPC.MOUNTD on server %s failed\n", client->server); exit(10); } printf("Connected to RPC.MOUNTD on %s:%d\n", client->server, client->mount_port); printf("Send NULL request to check if RPC.MOUNTD is actually running\n"); if (rpc_mount_null_async(rpc, mount_null_cb, client) != 0) { printf("Failed to send null request\n"); exit(10); } } void pmap_getport2_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; if (status == RPC_STATUS_ERROR) { printf("portmapper getport call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("portmapper getport call to server %s failed, status:%d\n", client->server, status); exit(10); } client->mount_port = *(uint32_t *)data; printf("GETPORT returned RPC.MOUNTD is on port:%d\n", client->mount_port); if (client->mount_port == 0) { printf("RPC.MOUNTD is not available on server : %s:%d\n", client->server, client->mount_port); exit(10); } printf("Disconnect socket from portmap server\n"); if (rpc_disconnect(rpc, "normal disconnect") != 0) { printf("Failed to disconnect socket to portmapper\n"); exit(10); } printf("Connect to RPC.MOUNTD on %s:%d\n", client->server, client->mount_port); if (rpc_connect_async(rpc, client->server, client->mount_port, mount_connect_cb, client) != 0) { printf("Failed to start connection\n"); exit(10); } } void pmap_getport1_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; if (status == RPC_STATUS_ERROR) { printf("portmapper getport call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("portmapper getport call to server %s failed, status:%d\n", client->server, status); exit(10); } client->rquota_port = *(uint32_t *)data; printf("GETPORT returned RPC.RQUOTAD on port:%d\n", client->rquota_port); if (client->rquota_port == 0) { printf("RPC.RQUOTAD is not available on server : %s:%d\n", client->server, client->rquota_port); // exit(10); } printf("Send getport request asking for MOUNT port\n"); if (rpc_pmap2_getport_async(rpc, MOUNT_PROGRAM, MOUNT_V3, IPPROTO_TCP, pmap_getport2_cb, client) != 0) { printf("Failed to send getport request\n"); exit(10); } } void pmap_dump_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; struct pmap2_dump_result *dr = data; struct pmap2_mapping_list *list = dr->list; if (status == RPC_STATUS_ERROR) { printf("portmapper null call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("portmapper null call to server %s failed, status:%d\n", client->server, status); exit(10); } printf("Got reply from server for PORTMAP/DUMP procedure.\n"); while (list) { printf("Prog:%d Vers:%d Protocol:%d Port:%d\n", list->map.prog, list->map.vers, list->map.prot, list->map.port); list = list->next; } printf("Send getport request asking for MOUNT port\n"); if (rpc_pmap2_getport_async(rpc, RQUOTA_PROGRAM, RQUOTA_V1, IPPROTO_TCP, pmap_getport1_cb, client) != 0) { printf("Failed to send getport request\n"); exit(10); } } void pmap_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; if (status == RPC_STATUS_ERROR) { printf("portmapper null call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("portmapper null call to server %s failed, status:%d\n", client->server, status); exit(10); } printf("Got reply from server for PORTMAP/NULL procedure.\n"); printf("Send PMAP/DUMP command\n"); if (rpc_pmap2_dump_async(rpc, pmap_dump_cb, client) != 0) { printf("Failed to send getport request\n"); exit(10); } } void pmap_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) { struct client *client = private_data; printf("pmap_connect_cb status:%d.\n", status); if (status != RPC_STATUS_SUCCESS) { printf("connection to portmapper on server %s failed\n", client->server); exit(10); } printf("Send NULL request to check if portmapper is actually running\n"); if (rpc_pmap2_null_async(rpc, pmap_null_cb, client) != 0) { printf("Failed to send null request\n"); exit(10); } } int main(int argc _U_, char *argv[] _U_) { struct rpc_context *rpc; struct pollfd pfd; struct client client; rpc = rpc_init_context(); if (rpc == NULL) { printf("failed to init context\n"); exit(10); } client.server = SERVER; client.export = EXPORT; client.is_finished = 0; if (rpc_connect_async(rpc, client.server, 111, pmap_connect_cb, &client) != 0) { printf("Failed to start connection\n"); exit(10); } for (;;) { pfd.fd = rpc_get_fd(rpc); pfd.events = rpc_which_events(rpc); if (poll(&pfd, 1, -1) < 0) { printf("Poll failed"); exit(10); } if (rpc_service(rpc, pfd.revents) < 0) { printf("rpc_service failed\n"); break; } if (client.is_finished) { break; } } rpc_destroy_context(rpc); rpc=NULL; printf("nfsclient finished\n"); return 0; } libnfs-libnfs-1.9.8/examples/nfsclient-sync.c000066400000000000000000000114041255745034100212100ustar00rootroot00000000000000/* Copyright (C) by Ronnie Sahlberg 2010 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 . */ #define _FILE_OFFSET_BITS 64 #define _GNU_SOURCE /* Example program using the highlevel sync interface */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #pragma comment(lib, "ws2_32.lib") WSADATA wsaData; #define PRId64 "ll" #else #include #include #include #ifndef AROS #include #endif #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" struct client { char *server; char *export; uint32_t mount_port; int is_finished; }; char buf[3*1024*1024+337]; void print_usage(void) { fprintf(stderr, "Usage: nfsclient-sync [-?|--help] [--usage] \n"); } int main(int argc, char *argv[]) { struct nfs_context *nfs = NULL; int i, ret, res; uint64_t offset; struct client client; struct nfs_stat_64 st; struct nfsfh *nfsfh; struct nfsdir *nfsdir; struct nfsdirent *nfsdirent; struct statvfs svfs; exports export, tmp; const char *url = NULL; char *server = NULL, *path = NULL, *strp; #ifdef WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { printf("Failed to start Winsock2\n"); exit(10); } #endif #ifdef AROS aros_init_socket(); #endif url = argv[1]; if (url == NULL) { fprintf(stderr, "No URL specified.\n"); print_usage(); exit(0); } if (strncmp(url, "nfs://", 6)) { fprintf(stderr, "Invalid URL specified.\n"); print_usage(); exit(0); } server = strdup(url + 6); if (server == NULL) { fprintf(stderr, "Failed to strdup server string\n"); exit(10); } if (server[0] == '/' || server[0] == '\0') { fprintf(stderr, "Invalid server string.\n"); free(server); exit(10); } strp = strchr(server, '/'); if (strp == NULL) { fprintf(stderr, "Invalid URL specified.\n"); print_usage(); free(server); exit(0); } path = strdup(strp); if (path == NULL) { fprintf(stderr, "Failed to strdup server string\n"); free(server); exit(10); } if (path[0] != '/') { fprintf(stderr, "Invalid path.\n"); free(server); free(path); exit(10); } *strp = 0; client.server = server; client.export = path; client.is_finished = 0; nfs = nfs_init_context(); if (nfs == NULL) { printf("failed to init context\n"); goto finished; } ret = nfs_mount(nfs, client.server, client.export); if (ret != 0) { printf("Failed to mount nfs share : %s\n", nfs_get_error(nfs)); goto finished; } ret = nfs_opendir(nfs, "/", &nfsdir); if (ret != 0) { printf("Failed to opendir(\"/\") %s\n", nfs_get_error(nfs)); exit(10); } while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { char path[1024]; if (!strcmp(nfsdirent->name, ".") || !strcmp(nfsdirent->name, "..")) { continue; } sprintf(path, "%s/%s", "/", nfsdirent->name); ret = nfs_stat64(nfs, path, &st); if (ret != 0) { fprintf(stderr, "Failed to stat(%s) %s\n", path, nfs_get_error(nfs)); continue; } switch (st.nfs_mode & S_IFMT) { #ifndef WIN32 case S_IFLNK: #endif case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; case S_IFCHR: printf("c"); break; case S_IFBLK: printf("b"); break; } printf("%c%c%c", "-r"[!!(st.nfs_mode & S_IRUSR)], "-w"[!!(st.nfs_mode & S_IWUSR)], "-x"[!!(st.nfs_mode & S_IXUSR)] ); printf("%c%c%c", "-r"[!!(st.nfs_mode & S_IRGRP)], "-w"[!!(st.nfs_mode & S_IWGRP)], "-x"[!!(st.nfs_mode & S_IXGRP)] ); printf("%c%c%c", "-r"[!!(st.nfs_mode & S_IROTH)], "-w"[!!(st.nfs_mode & S_IWOTH)], "-x"[!!(st.nfs_mode & S_IXOTH)] ); printf(" %2d", (int)st.nfs_nlink); printf(" %5d", (int)st.nfs_uid); printf(" %5d", (int)st.nfs_gid); printf(" %12" PRId64, st.nfs_size); printf(" %s\n", nfsdirent->name); } nfs_closedir(nfs, nfsdir); finished: free(server); free(path); if (nfs != NULL) { nfs_destroy_context(nfs); } return 0; } libnfs-libnfs-1.9.8/examples/portmap-client.c000066400000000000000000000275421255745034100212210ustar00rootroot00000000000000/* Copyright (C) by Ronnie Sahlberg 2014 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 . */ /* Example program using the lowlevel raw interface. * This allow accurate control of the exact commands that are being used. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WIN32 #include "win32_compat.h" #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #include #include #include #include #include #include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" #include "libnfs-raw-nfs.h" #include "libnfs-raw-portmap.h" #include "libnfs-raw-rquota.h" struct client { int is_finished; }; void pmap2_dump_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; struct pmap2_dump_result *dr = data; struct pmap2_mapping_list *list = dr->list; if (status == RPC_STATUS_ERROR) { printf("PORTMAP2/DUMP call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("PORTMAP2/DUMP call failed, status:%d\n", status); exit(10); } printf("PORTMAP2/DUMP:\n"); while (list) { printf(" Prog:%d Vers:%d Protocol:%d Port:%d\n", list->map.prog, list->map.vers, list->map.prot, list->map.port); list = list->next; } client->is_finished = 1; } void pmap3_dump_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; struct pmap3_dump_result *dr = data; struct pmap3_mapping_list *list = dr->list; if (status == RPC_STATUS_ERROR) { printf("PORTMAP3/DUMP call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("PORTMAP3/DUMP call failed, status:%d\n", status); exit(10); } printf("PORTMAP3/DUMP:\n"); while (list) { printf(" Prog:%d Vers:%d Netid:%s Addr:%s Owner:%s\n", list->map.prog, list->map.vers, list->map.netid, list->map.addr, list->map.owner); list = list->next; } client->is_finished = 1; } void pmap3_getaddr_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; struct pmap3_string_result *gar = data; if (status == RPC_STATUS_ERROR) { printf("PORTMAP3/GETADDR call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("PORTMAP3/GETADDR call failed, status:%d\n", status); exit(10); } printf("PORTMAP3/GETADDR:\n"); printf(" Addr:%s\n", gar->addr); client->is_finished = 1; } void pmap3_set_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; uint32_t res = *(uint32_t *)data; if (status == RPC_STATUS_ERROR) { printf("PORTMAP3/SET call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("PORTMAP3/SET call failed, status:%d\n", status); exit(10); } printf("PORTMAP3/SET:\n"); printf(" Res:%d\n", res); client->is_finished = 1; } void pmap3_unset_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; uint32_t res = *(uint32_t *)data; if (status == RPC_STATUS_ERROR) { printf("PORTMAP3/UNSET call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("PORTMAP3/UNSET call failed, status:%d\n", status); exit(10); } printf("PORTMAP3/UNSET:\n"); printf(" Res:%d\n", res); client->is_finished = 1; } void pmap3_gettime_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; time_t t = *(uint32_t *)data; if (status == RPC_STATUS_ERROR) { printf("PORTMAP3/GETTIME call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("PORTMAP3/GETTIME call failed, status:%d\n", status); exit(10); } printf("PORTMAP3/GETTIME:\n"); printf(" Time:%d %s\n", (int)t, ctime(&t)); client->is_finished = 1; } void pmap3_uaddr2taddr_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; struct pmap3_netbuf *nb = data; struct sockaddr_storage *ss; char host[256], port[6]; int i; if (status == RPC_STATUS_ERROR) { printf("PORTMAP3/UADDR2TADDR call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("PORTMAP3/UADDR2TADDR call failed, status:%d\n", status); exit(10); } printf("PORTMAP3/UADDR2TADDR:\n"); printf(" MaxLen:%d\n", nb->maxlen); printf(" "); for (i = 0; i < nb->maxlen; i++) { printf("%02x ", nb->buf.buf_val[i]); if (i %16 == 15) { printf("\n "); } } printf("\n"); printf(" ---\n"); ss = (struct sockaddr_storage *)&nb->buf.buf_val[0]; getnameinfo((struct sockaddr *)ss, sizeof(struct sockaddr_storage), &host[0], sizeof(host), &port[0], sizeof(port), NI_NUMERICHOST|NI_NUMERICSERV); switch (ss->ss_family) { case AF_INET: printf(" IPv4: %s:%s\n", &host[0], &port[0]); break; case AF_INET6: printf(" IPv6: %s:%s\n", &host[0], &port[0]); break; } client->is_finished = 1; } void pmap2_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; if (status == RPC_STATUS_ERROR) { printf("PORTMAP2/NULL call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("PORTMAP2/NULL call failed, status:%d\n", status); exit(10); } printf("PORTMAP2/NULL responded and server is alive\n"); client->is_finished = 1; } void pmap3_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; if (status == RPC_STATUS_ERROR) { printf("PORTMAP3/NULL call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("PORTMAP3/NULL call failed, status:%d\n", status); exit(10); } printf("PORTMAP3/NULL responded and server is alive\n"); client->is_finished = 1; } void pmap_null_cb(struct rpc_context *rpc, int status, void *data, void *private_data) { struct client *client = private_data; if (status == RPC_STATUS_ERROR) { printf("PORTMAP/NULL call failed with \"%s\"\n", (char *)data); exit(10); } if (status != RPC_STATUS_SUCCESS) { printf("PORTMAP/NULL call failed, status:%d\n", status); exit(10); } client->is_finished = 1; } void pmap_connect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) { struct client *client = private_data; if (status != RPC_STATUS_SUCCESS) { printf("connection to portmapper failed\n"); exit(10); } if (rpc_pmap2_null_async(rpc, pmap_null_cb, client) != 0) { printf("Failed to send null request\n"); exit(10); } } static void wait_until_finished(struct rpc_context *rpc, struct client *client) { struct pollfd pfd; client->is_finished = 0; for (;;) { pfd.fd = rpc_get_fd(rpc); pfd.events = rpc_which_events(rpc); if (poll(&pfd, 1, -1) < 0) { printf("Poll failed"); exit(10); } if (rpc_service(rpc, pfd.revents) < 0) { printf("rpc_service failed\n"); break; } if (client->is_finished) { break; } } } int main(int argc _U_, char *argv[] _U_) { struct rpc_context *rpc; struct client client; char *server = NULL; int i; int null2 = 0; int dump2 = 0; int null3 = 0; int set3 = 0; int unset3 = 0; int getaddr3 = 0; int dump3 = 0; int gettime3 = 0; int u2t3 = 0; int command_found = 0; int set3prog, set3vers; char *set3netid, *set3addr, *set3owner; int unset3prog, unset3vers; char *unset3netid, *unset3addr, *unset3owner; int getaddr3prog, getaddr3vers; char *getaddr3netid, *getaddr3addr, *getaddr3owner; char *u2t3string; rpc = rpc_init_context(); if (rpc == NULL) { printf("failed to init context\n"); exit(10); } for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "dump2")) { dump2 = 1; command_found++; } else if (!strcmp(argv[i], "null2")) { null2 = 1; command_found++; } else if (!strcmp(argv[i], "dump3")) { dump3 = 1; command_found++; } else if (!strcmp(argv[i], "gettime3")) { gettime3 = 1; command_found++; } else if (!strcmp(argv[i], "u2t3")) { u2t3 = 1; u2t3string = argv[++i]; command_found++; } else if (!strcmp(argv[i], "getaddr3")) { getaddr3 = 1; getaddr3prog = atoi(argv[++i]); getaddr3vers = atoi(argv[++i]); getaddr3netid = argv[++i]; getaddr3addr = argv[++i]; getaddr3owner = argv[++i]; command_found++; } else if (!strcmp(argv[i], "set3")) { set3 = 1; set3prog = atoi(argv[++i]); set3vers = atoi(argv[++i]); set3netid = argv[++i]; set3addr = argv[++i]; set3owner = argv[++i]; command_found++; } else if (!strcmp(argv[i], "null3")) { null3 = 1; command_found++; } else { server = argv[i]; } } if (command_found == 0 || server == NULL) { fprintf(stderr, "Usage: portmap-client \n"); exit(10); } if (rpc_connect_async(rpc, server, 111, pmap_connect_cb, &client) != 0) { printf("Failed to start connection\n"); exit(10); } wait_until_finished(rpc, &client); if (null2) { if (rpc_pmap2_null_async(rpc, pmap2_null_cb, &client) != 0) { printf("Failed to send NULL2 request\n"); exit(10); } wait_until_finished(rpc, &client); } if (dump2) { if (rpc_pmap2_dump_async(rpc, pmap2_dump_cb, &client) != 0) { printf("Failed to send DUMP2 request\n"); exit(10); } wait_until_finished(rpc, &client); } if (null3) { if (rpc_pmap3_null_async(rpc, pmap3_null_cb, &client) != 0) { printf("Failed to send NULL3 request\n"); exit(10); } wait_until_finished(rpc, &client); } if (dump3) { if (rpc_pmap3_dump_async(rpc, pmap3_dump_cb, &client) != 0) { printf("Failed to send DUMP3 request\n"); exit(10); } wait_until_finished(rpc, &client); } if (gettime3) { if (rpc_pmap3_gettime_async(rpc, pmap3_gettime_cb, &client) != 0) { printf("Failed to send GETTIME3 request\n"); exit(10); } wait_until_finished(rpc, &client); } if (u2t3) { if (rpc_pmap3_uaddr2taddr_async(rpc, u2t3string, pmap3_uaddr2taddr_cb, &client) != 0) { printf("Failed to send UADDR2TADDR3 request\n"); exit(10); } wait_until_finished(rpc, &client); } if (getaddr3) { struct pmap3_mapping map; map.prog = getaddr3prog; map.vers = getaddr3vers; map.netid = getaddr3netid; map.addr = getaddr3addr; map.owner = getaddr3owner; if (rpc_pmap3_getaddr_async(rpc, &map, pmap3_getaddr_cb, &client) != 0) { printf("Failed to send GETADDR3 request\n"); exit(10); } wait_until_finished(rpc, &client); } if (set3) { struct pmap3_mapping map; map.prog = set3prog; map.vers = set3vers; map.netid = set3netid; map.addr = set3addr; map.owner = set3owner; if (rpc_pmap3_set_async(rpc, &map, pmap3_set_cb, &client) != 0) { printf("Failed to send SET3 request\n"); exit(10); } wait_until_finished(rpc, &client); } if (unset3) { struct pmap3_mapping map; map.prog = unset3prog; map.vers = unset3vers; map.netid = unset3netid; map.addr = unset3addr; map.owner = unset3owner; if (rpc_pmap3_unset_async(rpc, &map, pmap3_unset_cb, &client) != 0) { printf("Failed to send UNSET3 request\n"); exit(10); } wait_until_finished(rpc, &client); } rpc_destroy_context(rpc); rpc=NULL; return 0; } libnfs-libnfs-1.9.8/include/000077500000000000000000000000001255745034100157125ustar00rootroot00000000000000libnfs-libnfs-1.9.8/include/Makefile.am000066400000000000000000000005441255745034100177510ustar00rootroot00000000000000nfscdir = $(includedir)/nfsc dist_nfsc_HEADERS = \ nfsc/libnfs.h \ nfsc/libnfs-raw.h \ nfsc/libnfs-zdr.h \ ../mount/libnfs-raw-mount.h \ ../portmap/libnfs-raw-portmap.h \ ../nfs/libnfs-raw-nfs.h \ ../nlm/libnfs-raw-nlm.h \ ../nsm/libnfs-raw-nsm.h \ ../rquota/libnfs-raw-rquota.h dist_noinst_HEADERS = \ libnfs-private.h \ slist.h libnfs-libnfs-1.9.8/include/libnfs-private.h000066400000000000000000000125251255745034100210150ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifndef _LIBNFS_PRIVATE_H_ #define _LIBNFS_PRIVATE_H_ #ifdef HAVE_CONFIG_H #include "config.h" /* HAVE_SOCKADDR_STORAGE ? */ #endif #ifndef WIN32 #include /* struct sockaddr_storage */ #endif #include "libnfs-zdr.h" #ifdef __cplusplus extern "C" { #endif #if !defined(HAVE_SOCKADDR_STORAGE) && !defined(WIN32) /* * RFC 2553: protocol-independent placeholder for socket addresses */ #define _SS_MAXSIZE 128 #define _SS_ALIGNSIZE (sizeof(double)) #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(unsigned char) * 2) #define _SS_PAD2SIZE (_SS_MAXSIZE - sizeof(unsigned char) * 2 - \ _SS_PAD1SIZE - _SS_ALIGNSIZE) struct sockaddr_storage { #ifdef HAVE_SOCKADDR_LEN unsigned char ss_len; /* address length */ unsigned char ss_family; /* address family */ #else unsigned short ss_family; #endif char __ss_pad1[_SS_PAD1SIZE]; double __ss_align; /* force desired structure storage alignment */ char __ss_pad2[_SS_PAD2SIZE]; }; #endif struct rpc_fragment { struct rpc_fragment *next; uint64_t size; char *data; }; #define RPC_CONTEXT_MAGIC 0xc6e46435 #define RPC_PARAM_UNDEFINED -1 /* * Queue is singly-linked but we hold on to the tail */ struct rpc_queue { struct rpc_pdu *head, *tail; }; #define HASHES 1024 #define NFS_RA_TIMEOUT 5 #define NFS_MAX_XFER_SIZE (1024 * 1024) struct rpc_context { uint32_t magic; int fd; int is_connected; char *error_string; rpc_cb connect_cb; void *connect_data; struct AUTH *auth; uint32_t xid; /* buffer used for encoding RPC PDU */ char *encodebuf; int encodebuflen; struct rpc_queue outqueue; struct sockaddr_storage udp_src; struct rpc_queue waitpdu[HASHES]; uint32_t inpos; char *inbuf; uint32_t inbuflen; /* special fields for UDP, which can sometimes be BROADCASTed */ int is_udp; struct sockaddr *udp_dest; int is_broadcast; /* track the address we connect to so we can auto-reconnect on session failure */ struct sockaddr_storage s; int auto_reconnect; /* fragment reassembly */ struct rpc_fragment *fragments; /* parameters passable via URL */ int tcp_syncnt; int uid; int gid; uint32_t readahead; int debug; }; struct rpc_pdu { struct rpc_pdu *next; uint32_t xid; ZDR zdr; uint32_t written; struct rpc_data outdata; rpc_cb cb; void *private_data; /* function to decode the zdr reply data and buffer to decode into */ zdrproc_t zdr_decode_fn; caddr_t zdr_decode_buf; uint32_t zdr_decode_bufsize; }; void rpc_reset_queue(struct rpc_queue *q); void rpc_enqueue(struct rpc_queue *q, struct rpc_pdu *pdu); void rpc_return_to_queue(struct rpc_queue *q, struct rpc_pdu *pdu); unsigned int rpc_hash_xid(uint32_t xid); struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_bufsize); void rpc_free_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu); int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu); int rpc_get_pdu_size(char *buf); int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size); void rpc_error_all_pdus(struct rpc_context *rpc, const char *error); void rpc_set_error(struct rpc_context *rpc, const char *error_string, ...) #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif ; void nfs_set_error(struct nfs_context *nfs, char *error_string, ...) #ifdef __GNUC__ __attribute__((format(printf, 2, 3))) #endif ; #define RPC_LOG(rpc, level, format, ...) \ do { \ if (level <= rpc->debug) { \ fprintf(stderr, "libnfs:%d " format "\n", level, ## __VA_ARGS__); \ } \ } while (0) const char *nfs_get_server(struct nfs_context *nfs); const char *nfs_get_export(struct nfs_context *nfs); /* we dont want to expose UDP to normal applications/users this is private to libnfs to use exclusively for broadcast RPC */ int rpc_bind_udp(struct rpc_context *rpc, char *addr, int port); int rpc_set_udp_destination(struct rpc_context *rpc, char *addr, int port, int is_broadcast); struct rpc_context *rpc_init_udp_context(void); struct sockaddr *rpc_get_recv_sockaddr(struct rpc_context *rpc); void rpc_set_autoreconnect(struct rpc_context *rpc); void rpc_unset_autoreconnect(struct rpc_context *rpc); void rpc_set_tcp_syncnt(struct rpc_context *rpc, int v); void rpc_set_uid(struct rpc_context *rpc, int uid); void rpc_set_gid(struct rpc_context *rpc, int gid); void rpc_set_readahead(struct rpc_context *rpc, uint32_t v); void rpc_set_debug(struct rpc_context *rpc, int level); int rpc_add_fragment(struct rpc_context *rpc, char *data, uint64_t size); void rpc_free_all_fragments(struct rpc_context *rpc); const struct nfs_fh3 *nfs_get_rootfh(struct nfs_context *nfs); #ifdef __cplusplus } #endif #endif /* !_LIBNFS_PRIVATE_H_ */ libnfs-libnfs-1.9.8/include/nfsc/000077500000000000000000000000001255745034100166435ustar00rootroot00000000000000libnfs-libnfs-1.9.8/include/nfsc/libnfs-raw.h000066400000000000000000002302031255745034100210600ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ /* * This is the lowlevel interface to access NFS resources. * Through this interface you have access to the full gamut of nfs and nfs related * protocol as well as the XDR encoded/decoded structures. */ #ifndef _LIBNFS_RAW_H_ #define _LIBNFS_RAW_H_ #include #include #ifdef __cplusplus extern "C" { #endif struct rpc_data { int size; unsigned char *data; }; struct rpc_context; struct rpc_context *rpc_init_context(void); void rpc_destroy_context(struct rpc_context *rpc); void rpc_set_auth(struct rpc_context *rpc, struct AUTH *auth); int rpc_get_fd(struct rpc_context *rpc); int rpc_which_events(struct rpc_context *rpc); int rpc_service(struct rpc_context *rpc, int revents); char *rpc_get_error(struct rpc_context *rpc); int rpc_queue_length(struct rpc_context *rpc); /* Utility function to get an RPC context from a NFS context. Useful for doing low level NFSACL * calls on a NFS context. */ struct rpc_context *nfs_get_rpc_context(struct nfs_context *nfs); /* This function returns the nfs_fh3 structure from a nfsfh structure. This allows to use a file onened with nfs_open() together with low-level rpc functions that thake a nfs filehandle */ struct nfs_fh3 *nfs_get_fh(struct nfsfh *nfsfh); /* Control what the next XID value to be used on the context will be. This can be used when multiple contexts are used to the same server to avoid that the two contexts have xid collissions. */ void rpc_set_next_xid(struct rpc_context *rpc, uint32_t xid); /* This function can be used to set the file descriptor used for * the RPC context. It is primarily useful when emulating dup2() * and similar or where you want full control of the filedescriptor numbers * used by the rpc socket. * * ... * oldfd = rpc_get_fd(rpc); * dup2(oldfd, newfd); * rpc_set_fd(rpc, newfd); * close(oldfd); * ... */ void rpc_set_fd(struct rpc_context *rpc, int fd); #define RPC_STATUS_SUCCESS 0 #define RPC_STATUS_ERROR 1 #define RPC_STATUS_CANCEL 2 /* * Async connection to the tcp port at server:port. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : The tcp connection was successfully established. * data is NULL. * RPC_STATUS_ERROR : The connection failed to establish. * data is the erro string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * : data is NULL. */ int rpc_connect_async(struct rpc_context *rpc, const char *server, int port, rpc_cb cb, void *private_data); /* * Async function to connect to a specific RPC program/version * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : The tcp connection was successfully established. * data is NULL. * RPC_STATUS_ERROR : The connection failed to establish. * data is the erro string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * : data is NULL. */ int rpc_connect_program_async(struct rpc_context *rpc, const char *server, int program, int version, rpc_cb cb, void *private_data); /* * When disconnecting a connection in flight. All commands in flight will be called with the callback * and status RPC_STATUS_ERROR. Data will be the error string for the disconnection. */ int rpc_disconnect(struct rpc_context *rpc, const char *error); /* * PORTMAP v2 FUNCTIONS */ /* * Call PORTMAPPER2/NULL * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call PORTMAPPER2/GETPORT. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is a (uint32_t *), containing the port returned. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap2_getport_async(struct rpc_context *rpc, int program, int version, int protocol, rpc_cb cb, void *private_data); /* * Call PORTMAPPER2/SET * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is a (uint32_t *), containing status * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap2_set_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data); /* * Call PORTMAPPER2/UNSET * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is a (uint32_t *), containing status * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap2_unset_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data); /* * Call PORTMAPPER2/DUMP. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is struct pmap2_dump_result. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap2_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call PORTMAPPER2/CALLIT. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon * data is a 'pmap2_call_result' pointer. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap2_callit_async(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data); /* * PORTMAP v3 FUNCTIONS */ /* * Call PORTMAPPER3/NULL * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call PORTMAPPER3/SET. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is uint32_t * * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct pmap3_mapping; EXTERN int rpc_pmap3_set_async(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data); /* * Call PORTMAPPER3/UNSET. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is uint32_t * * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap3_unset_async(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data); /* * Call PORTMAPPER3/GETADDR. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is struct pmap3_string_result. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap3_getaddr_async(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data); /* * Call PORTMAPPER3/DUMP. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is struct pmap3_dump_result. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap3_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call PORTMAPPER3/CALLIT. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon * data is a 'pmap3_call_result' pointer. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap3_callit_async(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data); /* * Call PORTMAPPER3/GETTIME. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is a uint32_t *. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap3_gettime_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call PORTMAPPER3/UADDR2TADDR. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is a struct pmap3_netbuf *. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_pmap3_uaddr2taddr_async(struct rpc_context *rpc, char *uaddr, rpc_cb cb, void *private_data); /* * Call PORTMAPPER3/TADDR2UADDR. * Function returns * 0 : The connection was initiated. Once the connection establish finishes, the callback will be invoked. * <0 : An error occured when trying to set up the connection. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the portmapper daemon. * data is a struct pmap3_string_result *. * RPC_STATUS_ERROR : An error occured when trying to contact the portmapper. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct pmap3_netbuf; EXTERN int rpc_pmap3_taddr2uaddr_async(struct rpc_context *rpc, struct pmap3_netbuf *netbuf, rpc_cb cb, void *private_data); /* * MOUNT v3 FUNCTIONS */ char *mountstat3_to_str(int stat); int mountstat3_to_errno(int error); /* * Call MOUNT3/NULL * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data is NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); EXTERN int rpc_mount_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call MOUNT3/MNT * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data is union mountres3. * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount3_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *exportname, void *private_data); EXTERN int rpc_mount_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *exportname, void *private_data); /* * Call MOUNT3/DUMP * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data is a mountlist. * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount3_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); EXTERN int rpc_mount_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call MOUNT3/UMNT * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount3_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *exportname, void *private_data); EXTERN int rpc_mount_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *exportname, void *private_data); /* * Call MOUNT3/UMNTALL * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount3_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); EXTERN int rpc_mount_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call MOUNT3/EXPORT * NOTE: You must include 'libnfs-raw-mount.h' to get the definitions of the * returned structures. * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data is a pointer to an exports pointer: * exports export = *(exports *)data; * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount3_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); EXTERN int rpc_mount_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * MOUNT v1 FUNCTIONS (Used with NFSv2) */ /* * Call MOUNT1/NULL * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data is NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call MOUNT1/MNT * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data is union mountres1. * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount1_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *exportname, void *private_data); /* * Call MOUNT1/DUMP * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data is a mountlist. * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount1_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call MOUNT1/UMNT * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount1_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *exportname, void *private_data); /* * Call MOUNT1/UMNTALL * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount1_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call MOUNT1/EXPORT * NOTE: You must include 'libnfs-raw-mount.h' to get the definitions of the * returned structures. * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the mount daemon. * data is a pointer to an exports pointer: * exports export = *(exports *)data; * RPC_STATUS_ERROR : An error occured when trying to contact the mount daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_mount1_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * NFS v3 FUNCTIONS */ struct nfs_fh3; char *nfsstat3_to_str(int error); int nfsstat3_to_errno(int error); /* * Call NFS3/NULL * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_nfs3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); EXTERN int rpc_nfs_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call NFS3/GETATTR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is GETATTR3res * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct GETATTR3args; EXTERN int rpc_nfs3_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct GETATTR3args *args, void *private_data); EXTERN int rpc_nfs_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); /* * Call NFS3/PATHCONF * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is PATHCONF3res * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct PATHCONF3args; EXTERN int rpc_nfs3_pathconf_async(struct rpc_context *rpc, rpc_cb cb, struct PATHCONF3args *args, void *private_data); EXTERN int rpc_nfs_pathconf_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); /* * Call NFS3/LOOKUP * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is LOOKUP3res * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct LOOKUP3args; EXTERN int rpc_nfs3_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct LOOKUP3args *args, void *private_data); EXTERN int rpc_nfs_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, void *private_data); /* * Call NFS3/ACCESS * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is ACCESS3res * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct ACCESS3args; EXTERN int rpc_nfs3_access_async(struct rpc_context *rpc, rpc_cb cb, struct ACCESS3args *args, void *private_data); EXTERN int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, int access, void *private_data); /* * Call NFS3/READ * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is READ3res * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct READ3args; EXTERN int rpc_nfs3_read_async(struct rpc_context *rpc, rpc_cb cb, struct READ3args *args, void *private_data); EXTERN int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t offset, uint64_t count, void *private_data); /* * Call NFS3/WRITE * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is WRITE3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct WRITE3args; EXTERN int rpc_nfs3_write_async(struct rpc_context *rpc, rpc_cb cb, struct WRITE3args *args, void *private_data); EXTERN int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, uint64_t offset, uint64_t count, int stable_how, void *private_data); /* * Call NFS3/COMMIT * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is COMMIT3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct COMMIT3args; EXTERN int rpc_nfs3_commit_async(struct rpc_context *rpc, rpc_cb cb, struct COMMIT3args *args, void *private_data); EXTERN int rpc_nfs_commit_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); /* * Call NFS3/SETATTR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is SETATTR3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct SETATTR3args; EXTERN int rpc_nfs3_setattr_async(struct rpc_context *rpc, rpc_cb cb, struct SETATTR3args *args, void *private_data); EXTERN int rpc_nfs_setattr_async(struct rpc_context *rpc, rpc_cb cb, struct SETATTR3args *args, void *private_data); /* * Call NFS3/MKDIR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is MKDIR3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct MKDIR3args; EXTERN int rpc_nfs3_mkdir_async(struct rpc_context *rpc, rpc_cb cb, struct MKDIR3args *args, void *private_data); EXTERN int rpc_nfs_mkdir_async(struct rpc_context *rpc, rpc_cb cb, struct MKDIR3args *args, void *private_data); /* * Call NFS3/RMDIR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is RMDIR3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct RMDIR3args; EXTERN int rpc_nfs3_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct RMDIR3args *args, void *private_data); EXTERN int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *dir, void *private_data); /* * Call NFS3/CREATE * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is CREATE3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct CREATE3args; EXTERN int rpc_nfs3_create_async(struct rpc_context *rpc, rpc_cb cb, struct CREATE3args *args, void *private_data); EXTERN int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, struct CREATE3args *args, void *private_data); /* * Call NFS3/MKNOD * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is MKNOD3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct MKNOD3args; EXTERN int rpc_nfs3_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct MKNOD3args *args, void *private_data); EXTERN int rpc_nfs_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, int mode, int major, int minor, void *private_data); /* * Call NFS3/REMOVE * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is REMOVE3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct REMOVE3args; EXTERN int rpc_nfs3_remove_async(struct rpc_context *rpc, rpc_cb cb, struct REMOVE3args *args, void *private_data); EXTERN int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, void *private_data); /* * Call NFS3/READDIR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is READDIR3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct READDIR3args; EXTERN int rpc_nfs3_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct READDIR3args *args, void *private_data); EXTERN int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data); /* * Call NFS3/READDIRPLUS * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is READDIRPLUS3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct READDIRPLUS3args; EXTERN int rpc_nfs3_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct READDIRPLUS3args *args, void *private_data); EXTERN int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data); /* * Call NFS3/FSSTAT * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is FSSTAT3res * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct FSSTAT3args; EXTERN int rpc_nfs3_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct FSSTAT3args *args, void *private_data); EXTERN int rpc_nfs_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); /* * Call NFS3/FSINFO * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is FSINFO3res * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct FSINFO3args; EXTERN int rpc_nfs3_fsinfo_async(struct rpc_context *rpc, rpc_cb cb, struct FSINFO3args *args, void *private_data); EXTERN int rpc_nfs_fsinfo_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data); /* * Call NFS3/READLINK * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is READLINK3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct READLINK3args; EXTERN int rpc_nfs3_readlink_async(struct rpc_context *rpc, rpc_cb cb, struct READLINK3args *args, void *private_data); EXTERN int rpc_nfs_readlink_async(struct rpc_context *rpc, rpc_cb cb, struct READLINK3args *args, void *private_data); /* * Call NFS3/SYMLINK * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is SYMLINK3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct SYMLINK3args; EXTERN int rpc_nfs3_symlink_async(struct rpc_context *rpc, rpc_cb cb, struct SYMLINK3args *args, void *private_data); EXTERN int rpc_nfs_symlink_async(struct rpc_context *rpc, rpc_cb cb, struct SYMLINK3args *args, void *private_data); /* * Call NFS3/RENAME * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is RENAME3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct RENAME3args; EXTERN int rpc_nfs3_rename_async(struct rpc_context *rpc, rpc_cb cb, struct RENAME3args *args, void *private_data); EXTERN int rpc_nfs_rename_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *olddir, char *oldname, struct nfs_fh3 *newdir, char *newname, void *private_data); /* * Call NFS3/LINK * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is LINK3res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct LINK3args; EXTERN int rpc_nfs3_link_async(struct rpc_context *rpc, rpc_cb cb, struct LINK3args *args, void *private_data); EXTERN int rpc_nfs_link_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *file, struct nfs_fh3 *newdir, char *newname, void *private_data); /* * NFS v2 FUNCTIONS */ /* * Call NFS2/NULL * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_nfs2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call NFS2/GETATTR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is GETATTR2res * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct GETATTR2args; EXTERN int rpc_nfs2_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct GETATTR2args *args, void *private_data); /* * Call NFS2/SETATTR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is SETATTR2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct SETATTR2args; EXTERN int rpc_nfs2_setattr_async(struct rpc_context *rpc, rpc_cb cb, struct SETATTR2args *args, void *private_data); /* * Call NFS2/LOOKUP * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is LOOKUP2res * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct LOOKUP2args; EXTERN int rpc_nfs2_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct LOOKUP2args *args, void *private_data); /* * Call NFS2/READLINK * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is READLINK2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct READLINK2args; EXTERN int rpc_nfs32_readlink_async(struct rpc_context *rpc, rpc_cb cb, struct READLINK2args *args, void *private_data); /* * Call NFS2/READ * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is READ2res * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct READ2args; EXTERN int rpc_nfs2_read_async(struct rpc_context *rpc, rpc_cb cb, struct READ2args *args, void *private_data); /* * Call NFS2/WRITE * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is WRITE2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct WRITE2args; EXTERN int rpc_nfs2_write_async(struct rpc_context *rpc, rpc_cb cb, struct WRITE2args *args, void *private_data); /* * Call NFS2/CREATE * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is CREATE2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct CREATE2args; EXTERN int rpc_nfs2_create_async(struct rpc_context *rpc, rpc_cb cb, struct CREATE2args *args, void *private_data); /* * Call NFS2/REMOVE * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is REMOVE2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct REMOVE2args; EXTERN int rpc_nfs2_remove_async(struct rpc_context *rpc, rpc_cb cb, struct REMOVE2args *args, void *private_data); /* * Call NFS2/RENAME * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is RENAME2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct RENAME2args; EXTERN int rpc_nfs2_rename_async(struct rpc_context *rpc, rpc_cb cb, struct RENAME2args *args, void *private_data); /* * Call NFS2/LINK * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is LINK2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct LINK2args; EXTERN int rpc_nfs2_link_async(struct rpc_context *rpc, rpc_cb cb, struct LINK2args *args, void *private_data); /* * Call NFS2/SYMLINK * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is SYMLINK2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct SYMLINK2args; EXTERN int rpc_nfs2_symlink_async(struct rpc_context *rpc, rpc_cb cb, struct SYMLINK2args *args, void *private_data); /* * Call NFS2/MKDIR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is MKDIR2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct MKDIR2args; EXTERN int rpc_nfs2_mkdir_async(struct rpc_context *rpc, rpc_cb cb, struct MKDIR2args *args, void *private_data); /* * Call NFS2/RMDIR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is RMDIR2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct RMDIR2args; EXTERN int rpc_nfs2_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct RMDIR2args *args, void *private_data); /* * Call NFS2/READDIR * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is READDIR2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct READDIR2args; EXTERN int rpc_nfs2_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct READDIR2args *args, void *private_data); /* * Call NFS2/STATFS * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is STATFS2res * * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct STATFS2args; EXTERN int rpc_nfs2_statfs_async(struct rpc_context *rpc, rpc_cb cb, struct STATFS2args *args, void *private_data); /* * RQUOTA FUNCTIONS */ char *rquotastat_to_str(int error); int rquotastat_to_errno(int error); /* * Call RQUOTA1/NULL * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the rquota daemon. * data is NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the rquota daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_rquota1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call RQUOTA1/GETQUOTA * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the rquota daemon. * data is a RQUOTA1res structure. * RPC_STATUS_ERROR : An error occured when trying to contact the rquota daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_rquota1_getquota_async(struct rpc_context *rpc, rpc_cb cb, char *exportname, int uid, void *private_data); /* * Call RQUOTA1/GETACTIVEQUOTA * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the rquota daemon. * data is a RQUOTA1res structure. * RPC_STATUS_ERROR : An error occured when trying to contact the rquota daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_rquota1_getactivequota_async(struct rpc_context *rpc, rpc_cb cb, char *exportname, int uid, void *private_data); /* * Call RQUOTA2/NULL * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the rquota daemon. * data is NULL. * RPC_STATUS_ERROR : An error occured when trying to contact the rquota daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ int rpc_rquota2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call RQUOTA2/GETQUOTA * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the rquota daemon. * data is a RQUOTA1res structure. * RPC_STATUS_ERROR : An error occured when trying to contact the rquota daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ int rpc_rquota2_getquota_async(struct rpc_context *rpc, rpc_cb cb, char *exportname, int type, int uid, void *private_data); /* * Call RQUOTA2/GETACTIVEQUOTA * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the rquota daemon. * data is a RQUOTA1res structure. * RPC_STATUS_ERROR : An error occured when trying to contact the rquota daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ int rpc_rquota2_getactivequota_async(struct rpc_context *rpc, rpc_cb cb, char *exportname, int type, int uid, void *private_data); /* * NFSACL functions */ /* * Call NFSACL/NULL * Call the NULL procedure for the NFSACL * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the rquota daemon. * data is NULL * RPC_STATUS_ERROR : An error occured when trying to contact the rquota daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_nfsacl_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call NFSACL/GETACL * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is a GETACL3res pointer * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct GETACL3args; EXTERN int rpc_nfsacl_getacl_async(struct rpc_context *rpc, rpc_cb cb, struct GETACL3args *args, void *private_data); /* * Call NFSACL/SETACL * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nfs daemon. * data is a SETACL3res pointer * RPC_STATUS_ERROR : An error occured when trying to contact the nfs daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct SETACL3args; EXTERN int rpc_nfsacl_setacl_async(struct rpc_context *rpc, rpc_cb cb, struct SETACL3args *args, void *private_data); /* * NLM functions */ char *nlmstat4_to_str(int stat); /* * Call NLM/NULL * Call the NULL procedure for the NLM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nlm daemon. * data is NULL * RPC_STATUS_ERROR : An error occured when trying to contact the nlm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_nlm4_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call NLM/TEST * Call the TEST procedure for the NLM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nlm daemon. * data is NLM4_TESTres * RPC_STATUS_ERROR : An error occured when trying to contact the nlm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct NLM4_TESTargs; EXTERN int rpc_nlm4_test_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_TESTargs *args, void *private_data); /* * Call NLM/LOCK * Call the LOCK procedure for the NLM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nlm daemon. * data is NLM4_LOCKres * RPC_STATUS_ERROR : An error occured when trying to contact the nlm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct NLM4_LOCKargs; EXTERN int rpc_nlm4_lock_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_LOCKargs *args, void *private_data); /* * Call NLM/CANCEL * Call the CANCEL procedure for the NLM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nlm daemon. * data is NLM4_CANCres * RPC_STATUS_ERROR : An error occured when trying to contact the nlm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct NLM4_CANCargs; EXTERN int rpc_nlm4_cancel_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_CANCargs *args, void *private_data); /* * Call NLM/UNLOCK * Call the UNLOCK procedure for the NLM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nlm daemon. * data is NLM4_UNLOCKres * RPC_STATUS_ERROR : An error occured when trying to contact the nlm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct NLM4_UNLOCKargs; EXTERN int rpc_nlm4_unlock_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_UNLOCKargs *args, void *private_data); /* * NSM functions */ char *nsmstat1_to_str(int stat); /* * Call NSM/NULL * Call the NULL procedure for the NSM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nsm daemon. * data is NULL * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_nsm1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call NSM/STAT * Call the STAT procedure for the NSM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nsm daemon. * data is NSM1_STATres * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct NSM1_STATargs; EXTERN int rpc_nsm1_stat_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_STATargs *args, void *private_data); /* * Call NSM/MON * Call the MON procedure for the NSM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nsm daemon. * data is NSM1_MONres * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct NSM1_MONargs; EXTERN int rpc_nsm1_mon_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_MONargs *args, void *private_data); /* * Call NSM/UNMON * Call the UNMON procedure for the NSM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nsm daemon. * data is NSM1_UNMONres * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct NSM1_UNMONargs; EXTERN int rpc_nsm1_unmon_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_UNMONargs *args, void *private_data); /* * Call NSM/UNMONALL * Call the UNMONALL procedure for the NSM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nsm daemon. * data is NSM1_UNMONALLres * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct NSM1_UNMONALLargs; EXTERN int rpc_nsm1_unmonall_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_UNMONALLargs *args, void *private_data); /* * Call NSM/SIMUCRASH * Call the SIMUCRASH procedure for the NSM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nsm daemon. * data is NULL * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ EXTERN int rpc_nsm1_simucrash_async(struct rpc_context *rpc, rpc_cb cb, void *private_data); /* * Call NSM/NOTIFY * Call the NOTIFY procedure for the NSM protocol * * Function returns * 0 : The call was initiated. The callback will be invoked when the call completes. * <0 : An error occured when trying to set up the call. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * RPC_STATUS_SUCCESS : We got a successful response from the nsm daemon. * data is NULL * RPC_STATUS_ERROR : An error occured when trying to contact the nsm daemon. * data is the error string. * RPC_STATUS_CANCEL : The connection attempt was aborted before it could complete. * data is NULL. */ struct NSM1_NOTIFYargs; EXTERN int rpc_nsm1_notify_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_NOTIFYargs *args, void *private_data); #ifdef __cplusplus } #endif #endif libnfs-libnfs-1.9.8/include/nfsc/libnfs-zdr.h000066400000000000000000000150161255745034100210710ustar00rootroot00000000000000/* Copyright (C) 2012 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ /* * This file contains definitions for the built in ZDR implementation. * This is a very limited ZDR subset that can only marshal to/from a momory buffer, * i.e. zdrmem_create() buffers. * It aims to be compatible with normal rpcgen generated functions. */ /************************************************************ * Definitions copied from RFC 5531 * and slightly modified. ************************************************************/ #ifndef _LIBNFS_ZDR_H_ #define _LIBNFS_ZDR_H_ #ifdef WIN32 #ifndef CADDR_T_DEFINED #define CADDR_T_DEFINED typedef char *caddr_t; #endif #endif #include #include #include #include #ifdef __cplusplus extern "C" { #endif #define _RPC_RPC_H 1 #define _RPC_ZDR_H 1 #define _RPC_AUTH_H 1 /* we dont need these */ typedef void CLIENT; struct svc_req { int _dummy_; }; typedef void SVCXPRT; #define ZDR_INLINE(...) NULL #define IZDR_PUT_U_LONG(...) assert(0) #define IZDR_GET_U_LONG(...) (assert(0), 0) #define IZDR_PUT_LONG(...) assert(0) #define IZDR_GET_LONG(...) (assert(0), 0) #define IZDR_PUT_BOOL(...) assert(0) #define IZDR_GET_BOOL(...) (assert(0), 0) #ifndef TRUE #define TRUE 1 #endif #ifndef FALSE #define FALSE 0 #endif enum zdr_op { ZDR_ENCODE = 0, ZDR_DECODE = 1 }; struct zdr_mem { struct zdr_mem *next; caddr_t buf; uint32_t size; }; struct ZDR { enum zdr_op x_op; caddr_t buf; int size; int pos; struct zdr_mem *mem; }; typedef struct ZDR ZDR; typedef uint32_t u_int; typedef uint32_t enum_t; typedef uint32_t bool_t; typedef int (*zdrproc_t) (ZDR *, void *,...); #define AUTH_NONE 0 #define AUTH_NULL 0 #define AUTH_UNIX 1 struct opaque_auth { uint32_t oa_flavor; caddr_t oa_base; uint32_t oa_length; }; extern struct opaque_auth _null_auth; struct AUTH { struct opaque_auth ah_cred; struct opaque_auth ah_verf; caddr_t ah_private; }; #define RPC_MSG_VERSION 2 enum msg_type { CALL = 0, REPLY = 1 }; enum reply_stat { MSG_ACCEPTED=0, MSG_DENIED=1 }; enum accept_stat { SUCCESS = 0, PROG_UNAVAIL = 1, PROG_MISMATCH = 2, PROC_UNAVAIL = 3, GARBAGE_ARGS = 4, SYSTEM_ERR = 5 }; enum reject_stat { RPC_MISMATCH = 0, AUTH_ERROR = 1 }; enum auth_stat { AUTH_OK=0, /* * failed at remote end */ AUTH_BADCRED = 1, /* bogus credentials (seal broken) */ AUTH_REJECTEDCRED = 2, /* client should begin new session */ AUTH_BADVERF = 3, /* bogus verifier (seal broken) */ AUTH_REJECTEDVERF = 4, /* verifier expired or was replayed */ AUTH_TOOWEAK = 5, /* rejected due to security reasons */ /* * failed locally */ AUTH_INVALIDRESP = 6, /* bogus response verifier */ AUTH_FAILED = 7 /* some unknown reason */ }; struct call_body { uint32_t rpcvers; uint32_t prog; uint32_t vers; uint32_t proc; struct opaque_auth cred; struct opaque_auth verf; }; struct accepted_reply { struct opaque_auth verf; uint32_t stat; union { struct { caddr_t where; zdrproc_t proc; } results; struct { uint32_t low; uint32_t high; } mismatch_info; } reply_data; }; struct rejected_reply { enum reject_stat stat; union { struct { uint32_t low; uint32_t high; } mismatch_info; enum auth_stat stat; } reject_data; }; struct reply_body { uint32_t stat; union { struct accepted_reply areply; struct rejected_reply rreply; } reply; }; struct rpc_msg { uint32_t xid; uint32_t direction; union { struct call_body cbody; struct reply_body rbody; } body; }; #define zdrmem_create libnfs_zdrmem_create void libnfs_zdrmem_create(ZDR *zdrs, const caddr_t addr, uint32_t size, enum zdr_op xop); #define zdr_destroy libnfs_zdr_destroy void libnfs_zdr_destroy(ZDR *zdrs); #define zdr_bytes libnfs_zdr_bytes bool_t libnfs_zdr_bytes(ZDR *zdrs, char **bufp, uint32_t *size, uint32_t maxsize); #define zdr_u_int libnfs_zdr_u_int bool_t libnfs_zdr_u_int(ZDR *zdrs, uint32_t *u); #define zdr_int libnfs_zdr_int bool_t libnfs_zdr_int(ZDR *zdrs, int32_t *i); #define zdr_uint64_t libnfs_zdr_uint64_t bool_t libnfs_zdr_uint64_t(ZDR *zdrs, uint64_t *u); #define zdr_int64_t libnfs_zdr_int64_t bool_t libnfs_zdr_int64_t(ZDR *zdrs, int64_t *i); #define zdr_enum libnfs_zdr_enum bool_t libnfs_zdr_enum(ZDR *zdrs, enum_t *e); #define zdr_bool libnfs_zdr_bool bool_t libnfs_zdr_bool(ZDR *zdrs, bool_t *b); #define zdr_void libnfs_zdr_void bool_t libnfs_zdr_void(void); #define zdr_pointer libnfs_zdr_pointer bool_t libnfs_zdr_pointer(ZDR *zdrs, char **objp, uint32_t size, zdrproc_t proc); #define zdr_opaque libnfs_zdr_opaque bool_t libnfs_zdr_opaque(ZDR *zdrs, char *objp, uint32_t size); #define zdr_string libnfs_zdr_string bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t maxsize); #define zdr_array libnfs_zdr_array bool_t libnfs_zdr_array(ZDR *zdrs, char **arrp, uint32_t *size, uint32_t maxsize, uint32_t elsize, zdrproc_t proc); #define zdr_setpos libnfs_zdr_setpos bool_t libnfs_zdr_setpos(ZDR *zdrs, uint32_t pos); #define zdr_getpos libnfs_zdr_getpos uint32_t libnfs_zdr_getpos(ZDR *zdrs); #define zdr_free libnfs_zdr_free void libnfs_zdr_free(zdrproc_t proc, char *objp); struct rpc_context; #define zdr_callmsg libnfs_zdr_callmsg bool_t libnfs_zdr_callmsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg); #define zdr_replymsg libnfs_zdr_replymsg bool_t libnfs_zdr_replymsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg); #define authnone_create libnfs_authnone_create struct AUTH *libnfs_authnone_create(void); #define authunix_create libnfs_authunix_create struct AUTH *libnfs_authunix_create(const char *host, uint32_t uid, uint32_t gid, uint32_t len, uint32_t *groups); #define authunix_create_default libnfs_authunix_create_default struct AUTH *libnfs_authunix_create_default(void); #define auth_destroy libnfs_auth_destroy void libnfs_auth_destroy(struct AUTH *auth); #ifdef __cplusplus } #endif #endif libnfs-libnfs-1.9.8/include/nfsc/libnfs.h000066400000000000000000001223021255745034100202710ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ /* * This is the highlevel interface to access NFS resources using a posix-like interface */ #ifndef _LIBNFS_H_ #define _LIBNFS_H_ #include #if defined(ANDROID) #include #endif #if defined(AROS) #include #endif #if defined(__APPLE__) && defined(__MACH__) #include #endif #ifdef __cplusplus extern "C" { #endif #define LIBNFS_FEATURE_READAHEAD #define LIBNFS_FEATURE_DEBUG #define NFS_BLKSIZE 4096 struct nfs_context; struct rpc_context; struct nfs_url { char *server; char *path; char *file; }; #if defined(WIN32) #define EXTERN __declspec( dllexport ) #else #define EXTERN #endif #if defined(WIN32) struct statvfs { uint32_t f_bsize; uint32_t f_frsize; uint64_t f_blocks; uint64_t f_bfree; uint64_t f_bavail; uint32_t f_files; uint32_t f_ffree; uint32_t f_favail; uint32_t f_fsid; uint32_t f_flag; uint32_t f_namemax; }; struct utimbuf { time_t actime; time_t modtime; }; #define R_OK 4 #define W_OK 2 #define X_OK 1 #endif /* * Used for interfacing the async version of the api into an external eventsystem */ EXTERN int nfs_get_fd(struct nfs_context *nfs); EXTERN int nfs_which_events(struct nfs_context *nfs); EXTERN int nfs_service(struct nfs_context *nfs, int revents); EXTERN int nfs_queue_length(struct nfs_context *nfs); /* * Used if you need different credentials than the default for the current user. */ struct AUTH; EXTERN void nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth); /* * When an operation failed, this function can extract a detailed error string. */ EXTERN char *nfs_get_error(struct nfs_context *nfs); /* * Callback for all ASYNC nfs functions */ typedef void (*nfs_cb)(int err, struct nfs_context *nfs, void *data, void *private_data); /* * Callback for all ASYNC rpc functions */ typedef void (*rpc_cb)(struct rpc_context *rpc, int status, void *data, void *private_data); /* * NFS CONTEXT. */ /* * Create an NFS c, the context. * Function returns * NULL : Failed to create a context. * *nfs : A pointer to an nfs context. */ EXTERN struct nfs_context *nfs_init_context(void); /* * Destroy an nfs context. */ EXTERN void nfs_destroy_context(struct nfs_context *nfs); /* * URL parsing functions. * These functions all parse a URL of the form * nfs://server/path/file?argv=val[&arg=val]* * and returns a nfs_url. * * Apart from parsing the URL the functions will also update * the nfs context to reflect settings controlled via url arguments. * * Current URL arguments are : * tcp-syncnt= : Number of SYNs to send during the seccion establish * before failing settin up the tcp connection to the * server. * uid= : UID value to use when talking to the server. * default it 65534 on Windows and getuid() on unixen. * gid= : GID value to use when talking to the server. * default it 65534 on Windows and getgid() on unixen. * readahead= : Enable readahead for files and set the maximum amount * of readahead to . */ /* * Parse a complete NFS URL including, server, path and * filename. Fail if any component is missing. */ EXTERN struct nfs_url *nfs_parse_url_full(struct nfs_context *nfs, const char *url); /* * Parse an NFS URL, but do not split path and file. File * in the resulting struct remains NULL. */ EXTERN struct nfs_url *nfs_parse_url_dir(struct nfs_context *nfs, const char *url); /* * Parse an NFS URL, but do not fail if file, path or even server is missing. * Check elements of the resulting struct for NULL. */ EXTERN struct nfs_url *nfs_parse_url_incomplete(struct nfs_context *nfs, const char *url); /* * Free the URL struct returned by the nfs_parse_url_* functions. */ EXTERN void nfs_destroy_url(struct nfs_url *url); struct nfsfh; /* * Get the maximum supported READ3 size by the server */ EXTERN uint64_t nfs_get_readmax(struct nfs_context *nfs); /* * Get the maximum supported WRITE3 size by the server */ EXTERN uint64_t nfs_get_writemax(struct nfs_context *nfs); /* * MODIFY CONNECT PARAMTERS */ EXTERN void nfs_set_tcp_syncnt(struct nfs_context *nfs, int v); EXTERN void nfs_set_uid(struct nfs_context *nfs, int uid); EXTERN void nfs_set_gid(struct nfs_context *nfs, int gid); EXTERN void nfs_set_readahead(struct nfs_context *nfs, uint32_t v); EXTERN void nfs_set_debug(struct nfs_context *nfs, int level); /* * MOUNT THE EXPORT */ /* * Async nfs mount. * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_mount_async(struct nfs_context *nfs, const char *server, const char *exportname, nfs_cb cb, void *private_data); /* * Sync nfs mount. * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_mount(struct nfs_context *nfs, const char *server, const char *exportname); /* * STAT() */ /* * Async stat() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is struct stat * * -errno : An error occured. * data is the error string. */ /* This function is deprecated. Use nfs_stat64_async() instead */ struct stat; EXTERN int nfs_stat_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync stat() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ /* This function is deprecated. Use nfs_stat64() instead */ #ifdef WIN32 EXTERN int nfs_stat(struct nfs_context *nfs, const char *path, struct __stat64 *st); #else EXTERN int nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st); #endif /* nfs_stat64 * 64 bit version if stat. All fields are always 64bit. * Use these functions instead of nfs_stat[_async](), especially if you * have weird stat structures. */ /* * STAT() */ struct nfs_stat_64 { uint64_t nfs_dev; uint64_t nfs_ino; uint64_t nfs_mode; uint64_t nfs_nlink; uint64_t nfs_uid; uint64_t nfs_gid; uint64_t nfs_rdev; uint64_t nfs_size; uint64_t nfs_blksize; uint64_t nfs_blocks; uint64_t nfs_atime; uint64_t nfs_mtime; uint64_t nfs_ctime; uint64_t nfs_atime_nsec; uint64_t nfs_mtime_nsec; uint64_t nfs_ctime_nsec; uint64_t nfs_used; }; /* * Async stat() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is struct nfs_stat_64 * * -errno : An error occured. * data is the error string. */ EXTERN int nfs_stat64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync stat() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_stat64(struct nfs_context *nfs, const char *path, struct nfs_stat_64 *st); /* * Async stat() * * Like stat except if the destination is a symbolic link, it acts on the * symbolic link itself. * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is struct nfs_stat_64 * * -errno : An error occured. * data is the error string. */ EXTERN int nfs_lstat64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync stat() * * Like stat except if the destination is a symbolic link, it acts on the * symbolic link itself. * * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_lstat64(struct nfs_context *nfs, const char *path, struct nfs_stat_64 *st); /* * FSTAT() */ /* * Async fstat(nfsfh *) * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is struct stat * * -errno : An error occured. * data is the error string. */ /* This function is deprecated. Use nfs_fstat64_async() instead */ EXTERN int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data); /* * Sync fstat(nfsfh *) * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ #ifdef WIN32 EXTERN int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct __stat64 *st); #else EXTERN int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st); #endif /* nfs_fstat64 * 64 bit version of fstat. All fields are always 64bit. * Use these functions instead of nfs_fstat[_async](), especially if you * have weird stat structures. */ /* * FSTAT() */ /* * Async fstat(nfsfh *) * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is struct stat * * -errno : An error occured. * data is the error string. */ EXTERN int nfs_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data); /* * Sync fstat(nfsfh *) * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_fstat64(struct nfs_context *nfs, struct nfsfh *nfsfh, struct nfs_stat_64 *st); /* * UMASK() never blocks, so no special aync/async versions are available */ /* * Sync umask() * Function returns the old mask. */ EXTERN uint16_t nfs_umask(struct nfs_context *nfs, uint16_t mask); /* * OPEN() */ /* * Async open() * * mode is a combination of the flags : * O_RDOLNY, O_WRONLY, O_RDWR , O_SYNC, O_APPEND, O_TRUNC * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * Supported flags are * O_APPEND * O_RDONLY * O_WRONLY * O_RDWR * O_SYNC * O_TRUNC (Only valid with O_RDWR or O_WRONLY. Ignored otherwise.) * * When the callback is invoked, status indicates the result: * 0 : Success. * data is a struct *nfsfh; * The nfsfh is close using nfs_close(). * -errno : An error occured. * data is the error string. */ EXTERN int nfs_open_async(struct nfs_context *nfs, const char *path, int flags, nfs_cb cb, void *private_data); /* * Sync open() * Function returns * 0 : The operation was successfull. *nfsfh is filled in. * -errno : The command failed. */ EXTERN int nfs_open(struct nfs_context *nfs, const char *path, int flags, struct nfsfh **nfsfh); /* * CLOSE */ /* * Async close(nfsfh) * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data); /* * Sync close(nfsfh) * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_close(struct nfs_context *nfs, struct nfsfh *nfsfh); /* * PREAD() */ /* * Async pread() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * >=0 : Success. * status is numer of bytes read. * data is a pointer to the returned data. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, nfs_cb cb, void *private_data); /* * Sync pread() * Function returns * >=0 : numer of bytes read. * -errno : An error occured. */ EXTERN int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf); /* * READ() */ /* * Async read() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * >=0 : Success. * status is numer of bytes read. * data is a pointer to the returned data. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, nfs_cb cb, void *private_data); /* * Sync read() * Function returns * >=0 : numer of bytes read. * -errno : An error occured. */ EXTERN int nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf); /* * PWRITE() */ /* * Async pwrite() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * >=0 : Success. * status is numer of bytes written. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf, nfs_cb cb, void *private_data); /* * Sync pwrite() * Function returns * >=0 : numer of bytes written. * -errno : An error occured. */ EXTERN int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf); /* * WRITE() */ /* * Async write() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * >=0 : Success. * status is numer of bytes written. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf, nfs_cb cb, void *private_data); /* * Sync write() * Function returns * >=0 : numer of bytes written. * -errno : An error occured. */ EXTERN int nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf); /* * LSEEK() */ /* * Async lseek() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * >=0 : Success. * data is uint64_t * for the current position. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset, int whence, nfs_cb cb, void *private_data); /* * Sync lseek() * Function returns * >=0 : numer of bytes read. * -errno : An error occured. */ EXTERN int nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset, int whence, uint64_t *current_offset); /* * FSYNC() */ /* * Async fsync() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data); /* * Sync fsync() * Function returns * 0 : Success * -errno : An error occured. */ EXTERN int nfs_fsync(struct nfs_context *nfs, struct nfsfh *nfsfh); /* * TRUNCATE() */ /* * Async truncate() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length, nfs_cb cb, void *private_data); /* * Sync truncate() * Function returns * 0 : Success * -errno : An error occured. */ EXTERN int nfs_truncate(struct nfs_context *nfs, const char *path, uint64_t length); /* * FTRUNCATE() */ /* * Async ftruncate() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length, nfs_cb cb, void *private_data); /* * Sync ftruncate() * Function returns * 0 : Success * -errno : An error occured. */ EXTERN int nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length); /* * MKDIR() */ /* * Async mkdir() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_mkdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync mkdir() * Function returns * 0 : Success * -errno : An error occured. */ EXTERN int nfs_mkdir(struct nfs_context *nfs, const char *path); /* * RMDIR() */ /* * Async rmdir() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync rmdir() * Function returns * 0 : Success * -errno : An error occured. */ EXTERN int nfs_rmdir(struct nfs_context *nfs, const char *path); /* * CREAT() */ /* * Async creat() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is a struct *nfsfh; * -errno : An error occured. * data is the error string. */ EXTERN int nfs_creat_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); /* * Sync creat() * Function returns * 0 : Success * -errno : An error occured. */ EXTERN int nfs_creat(struct nfs_context *nfs, const char *path, int mode, struct nfsfh **nfsfh); /* * Async create() * * Same as nfs_creat_async but allows passing flags: * O_APPEND * O_SYNC * O_EXCL * O_TRUNC * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is a struct *nfsfh; * -errno : An error occured. * data is the error string. */ EXTERN int nfs_create_async(struct nfs_context *nfs, const char *path, int flags, int mode, nfs_cb cb, void *private_data); /* * Sync create() * Function returns * 0 : Success * -errno : An error occured. */ EXTERN int nfs_create(struct nfs_context *nfs, const char *path, int flags, int mode, struct nfsfh **nfsfh); /* * MKNOD() */ /* * Async mknod() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * -errno : An error occured. * data is the error string. */ EXTERN int nfs_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev, nfs_cb cb, void *private_data); /* * Sync mknod() * Function returns * 0 : Success * -errno : An error occured. */ EXTERN int nfs_mknod(struct nfs_context *nfs, const char *path, int mode, int dev); /* * UNLINK() */ /* * Async unlink() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync unlink() * Function returns * 0 : Success * -errno : An error occured. */ EXTERN int nfs_unlink(struct nfs_context *nfs, const char *path); /* * OPENDIR() */ struct nfsdir; /* * Async opendir() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When struct nfsdir * is returned, this resource is closed/freed by calling nfs_closedir() * * When the callback is invoked, status indicates the result: * 0 : Success. * data is struct nfsdir * * -errno : An error occured. * data is the error string. */ EXTERN int nfs_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync opendir() * Function returns * 0 : Success * -errno : An error occured. */ EXTERN int nfs_opendir(struct nfs_context *nfs, const char *path, struct nfsdir **nfsdir); /* * READDIR() */ struct nfsdirent { struct nfsdirent *next; char *name; uint64_t inode; /* Some extra fields we get for free through the READDIRPLUS3 call. You need libnfs-raw-nfs.h for type/mode constants */ uint32_t type; /* NF3REG, NF3DIR, NF3BLK, ... */ uint32_t mode; uint64_t size; struct timeval atime; struct timeval mtime; struct timeval ctime; uint32_t uid; uint32_t gid; uint32_t nlink; uint64_t dev; uint64_t rdev; uint64_t blksize; uint64_t blocks; uint64_t used; uint32_t atime_nsec; uint32_t mtime_nsec; uint32_t ctime_nsec; }; /* * nfs_readdir() never blocks, so no special sync/async versions are available */ EXTERN struct nfsdirent *nfs_readdir(struct nfs_context *nfs, struct nfsdir *nfsdir); /* * CLOSEDIR() */ /* * nfs_closedir() never blocks, so no special sync/async versions are available */ EXTERN void nfs_closedir(struct nfs_context *nfs, struct nfsdir *nfsdir); /* * CHDIR() */ /* * Async chdir() * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL; * -errno : An error occured. * data is the error string. */ EXTERN int nfs_chdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync chdir() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_chdir(struct nfs_context *nfs, const char *path); /* * GETCWD() */ /* * nfs_getcwd() never blocks, so no special sync/async versions are available */ /* * Sync getcwd() * This function returns a pointer to the current working directory. * This pointer is only stable until the next [f]chdir or when the * context is destroyed. * * Function returns * 0 : The operation was successfull and *cwd is filled in. * -errno : The command failed. */ EXTERN void nfs_getcwd(struct nfs_context *nfs, const char **cwd); /* * STATVFS() */ /* * Async statvfs() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is struct statvfs * * -errno : An error occured. * data is the error string. */ struct statvfs; EXTERN int nfs_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync statvfs() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs); /* * READLINK() */ /* * Async readlink() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is a char * * data is only valid during the callback and is automatically freed when the callback returns. * -errno : An error occured. * data is the error string. */ struct statvfs; EXTERN int nfs_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync readlink() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, int bufsize); /* * CHMOD() */ /* * Async chmod() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); /* * Sync chmod() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_chmod(struct nfs_context *nfs, const char *path, int mode); /* * Async chmod() * * Like chmod except if the destination is a symbolic link, it acts on the * symbolic link itself. * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_lchmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); /* * Sync chmod() * * Like chmod except if the destination is a symbolic link, it acts on the * symbolic link itself. * * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_lchmod(struct nfs_context *nfs, const char *path, int mode); /* * FCHMOD() */ /* * Async fchmod() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, nfs_cb cb, void *private_data); /* * Sync fchmod() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_fchmod(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode); /* * CHOWN() */ /* * Async chown() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data); /* * Sync chown() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid); /* * Async chown() * * Like chown except if the destination is a symbolic link, it acts on the * symbolic link itself. * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_lchown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data); /* * Sync chown() * * Like chown except if the destination is a symbolic link, it acts on the * symbolic link itself. * * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_lchown(struct nfs_context *nfs, const char *path, int uid, int gid); /* * FCHOWN() */ /* * Async fchown() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid, nfs_cb cb, void *private_data); /* * Sync fchown() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_fchown(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid); /* * UTIMES() */ /* * Async utimes() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_utimes_async(struct nfs_context *nfs, const char *path, struct timeval *times, nfs_cb cb, void *private_data); /* * Sync utimes() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_utimes(struct nfs_context *nfs, const char *path, struct timeval *times); /* * Async utimes() * * Like utimes except if the destination is a symbolic link, it acts on the * symbolic link itself. * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_lutimes_async(struct nfs_context *nfs, const char *path, struct timeval *times, nfs_cb cb, void *private_data); /* * Sync utimes() * * Like utimes except if the destination is a symbolic link, it acts on the * symbolic link itself. * * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_lutimes(struct nfs_context *nfs, const char *path, struct timeval *times); /* * UTIME() */ /* * Async utime() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ struct utimbuf; EXTERN int nfs_utime_async(struct nfs_context *nfs, const char *path, struct utimbuf *times, nfs_cb cb, void *private_data); /* * Sync utime() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_utime(struct nfs_context *nfs, const char *path, struct utimbuf *times); /* * ACCESS() */ /* * Async access() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_access_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data); /* * Sync access() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_access(struct nfs_context *nfs, const char *path, int mode); /* * ACCESS2() */ /* * Async access2() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * >= 0 : A mask of R_OK, W_OK and X_OK indicating which permissions are * available. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_access2_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data); /* * Sync access() * Function returns * >= 0 : A mask of R_OK, W_OK and X_OK indicating which permissions are * available. * -errno : The command failed. */ EXTERN int nfs_access2(struct nfs_context *nfs, const char *path); /* * SYMLINK() */ /* * Async symlink() * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_symlink_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data); /* * Sync symlink() * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_symlink(struct nfs_context *nfs, const char *oldpath, const char *newpath); /* * RENAME() */ /* * Async rename(, ) * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data); /* * Sync rename(, ) * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_rename(struct nfs_context *nfs, const char *oldpath, const char *newpath); /* * LINK() */ /* * Async link(, ) * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is NULL * -errno : An error occured. * data is the error string. */ EXTERN int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data); /* * Sync link(, ) * Function returns * 0 : The operation was successfull. * -errno : The command failed. */ EXTERN int nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath); /* * GETEXPORTS() */ /* * Async getexports() * NOTE: You must include 'libnfs-raw-mount.h' to get the definitions of the * returned structures. * * This function will return the list of exports from an NFS server. * * Function returns * 0 : The operation was initiated. Once the operation finishes, the callback will be invoked. * <0 : An error occured when trying to set up the operation. The callback will not be invoked. * * When the callback is invoked, status indicates the result: * 0 : Success. * data is a pointer to an exports pointer: * exports export = *(exports *)data; * -errno : An error occured. * data is the error string. */ EXTERN int mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb cb, void *private_data); /* * Sync getexports() * Function returns * NULL : something failed * exports export : a linked list of exported directories * * returned data must be freed by calling mount_free_export_list(exportnode); */ EXTERN struct exportnode *mount_getexports(const char *server); EXTERN void mount_free_export_list(struct exportnode *exports); struct nfs_server_list { struct nfs_server_list *next; char *addr; }; /* * Sync find_local_servers() * This function will probe all local networks for NFS server. This function will * block for one second while awaiting for all nfs servers to respond. * * Function returns * NULL : something failed * * struct nfs_server_list : a linked list of all discovered servers * * returned data must be freed by nfs_free_srvr_list(srv); */ struct nfs_server_list *nfs_find_local_servers(void); void free_nfs_srvr_list(struct nfs_server_list *srv); #ifdef __cplusplus } #endif #endif /* !_LIBNFS_H_ */ libnfs-libnfs-1.9.8/include/slist.h000066400000000000000000000032021255745034100172160ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifndef _LIBNFS_SLIST_H_ #define _LIBNFS_SLIST_H_ #define LIBNFS_LIST_ADD(list, item) \ do { \ (item)->next = (*list); \ (*list) = (item); \ } while (0); #define LIBNFS_LIST_ADD_END(list, item) \ if ((*list) == NULL) { \ LIBNFS_LIST_ADD((list), (item)); \ } else { \ void *head = (*list); \ while ((*list)->next) \ (*list) = (*list)->next; \ (*list)->next = (item); \ (item)->next = NULL; \ (*list) = head; \ } #define LIBNFS_LIST_REMOVE(list, item) \ if ((*list) == (item)) { \ (*list) = (item)->next; \ } else { \ void *head = (*list); \ while ((*list)->next && (*list)->next != (item)) \ (*list) = (*list)->next; \ if ((*list)->next != NULL) { \ (*list)->next = (*list)->next->next; \ } \ (*list) = head; \ } #endif /* !_LIBNFS_SLIST_H_ */ libnfs-libnfs-1.9.8/lib/000077500000000000000000000000001255745034100150355ustar00rootroot00000000000000libnfs-libnfs-1.9.8/lib/Makefile.am000066400000000000000000000013621255745034100170730ustar00rootroot00000000000000AM_CFLAGS=$(WARN_CFLAGS) lib_LTLIBRARIES = libnfs.la libnfs_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc \ -I$(abs_top_srcdir)/mount \ -I$(abs_top_srcdir)/nfs \ -I$(abs_top_srcdir)/nlm \ -I$(abs_top_srcdir)/nsm \ -I$(abs_top_srcdir)/portmap \ -I$(abs_top_srcdir)/rquota \ "-D_U_=__attribute__((unused))" libnfs_la_SOURCES = \ init.c \ libnfs.c \ libnfs-sync.c \ libnfs-zdr.c \ pdu.c \ socket.c SOCURRENT=9 SOREVISION=0 SOAGE=1 libnfs_la_LDFLAGS = -version-info $(SOCURRENT):$(SOREVISION):$(SOAGE) libnfs_la_LIBADD = \ ../mount/libmount.la \ ../nfs/libnfs.la \ ../nlm/libnlm.la \ ../nsm/libnsm.la \ ../portmap/libportmap.la \ ../rquota/librquota.la libnfs-libnfs-1.9.8/lib/init.c000066400000000000000000000143731255745034100161540ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #endif #define _GNU_SOURCE #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #include #include #include #include #include #include #include "slist.h" #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" struct rpc_context *rpc_init_context(void) { struct rpc_context *rpc; static uint32_t salt = 0; unsigned int i; rpc = malloc(sizeof(struct rpc_context)); if (rpc == NULL) { return NULL; } memset(rpc, 0, sizeof(struct rpc_context)); rpc->magic = RPC_CONTEXT_MAGIC; /* Allow NFS_MAX_XFER_SIZE of data (for writes) and some */ rpc->encodebuflen = NFS_MAX_XFER_SIZE + 4096; rpc->encodebuf = malloc(rpc->encodebuflen); if (rpc->encodebuf == NULL) { free(rpc); return NULL; } rpc->inbuflen = 2 * (NFS_MAX_XFER_SIZE + 4096); rpc->inbuf = malloc(rpc->inbuflen); if (rpc->inbuf == NULL) { free(rpc); return NULL; } rpc->auth = authunix_create_default(); if (rpc->auth == NULL) { free(rpc->encodebuf); free(rpc); return NULL; } rpc->xid = salt + time(NULL) + (getpid() << 16); salt += 0x01000000; rpc->fd = -1; rpc->tcp_syncnt = RPC_PARAM_UNDEFINED; #if defined(WIN32) || defined(ANDROID) rpc->uid = 65534; rpc->gid = 65534; #else rpc->uid = getuid(); rpc->gid = getgid(); #endif rpc_reset_queue(&rpc->outqueue); for (i = 0; i < HASHES; i++) rpc_reset_queue(&rpc->waitpdu[i]); return rpc; } void rpc_set_readahead(struct rpc_context *rpc, uint32_t v) { assert(rpc->magic == RPC_CONTEXT_MAGIC); rpc->readahead = v; } void rpc_set_debug(struct rpc_context *rpc, int level) { assert(rpc->magic == RPC_CONTEXT_MAGIC); rpc->debug = level; } struct rpc_context *rpc_init_udp_context(void) { struct rpc_context *rpc; rpc = rpc_init_context(); if (rpc != NULL) { rpc->is_udp = 1; } return rpc; } void rpc_set_auth(struct rpc_context *rpc, struct AUTH *auth) { assert(rpc->magic == RPC_CONTEXT_MAGIC); if (rpc->auth != NULL) { auth_destroy(rpc->auth); } rpc->auth = auth; } static void rpc_set_uid_gid(struct rpc_context *rpc, int uid, int gid) { if (uid != rpc->uid || gid != rpc->gid) { struct AUTH *auth = libnfs_authunix_create("libnfs", uid, gid, 0, NULL); if (auth != NULL) { rpc_set_auth(rpc, auth); rpc->uid = uid; rpc->gid = gid; } } } void rpc_set_uid(struct rpc_context *rpc, int uid) { rpc_set_uid_gid(rpc, uid, rpc->gid); } void rpc_set_gid(struct rpc_context *rpc, int gid) { rpc_set_uid_gid(rpc, rpc->uid, gid); } void rpc_set_error(struct rpc_context *rpc, const char *error_string, ...) { va_list ap; char *old_error_string = rpc->error_string; assert(rpc->magic == RPC_CONTEXT_MAGIC); va_start(ap, error_string); rpc->error_string = malloc(1024); vsnprintf(rpc->error_string, 1024, error_string, ap); va_end(ap); fprintf(stderr, "libnfs error: %s\n", rpc->error_string); if (old_error_string != NULL) { free(old_error_string); } } char *rpc_get_error(struct rpc_context *rpc) { assert(rpc->magic == RPC_CONTEXT_MAGIC); return rpc->error_string; } void rpc_error_all_pdus(struct rpc_context *rpc, const char *error) { struct rpc_pdu *pdu; unsigned int i; assert(rpc->magic == RPC_CONTEXT_MAGIC); while ((pdu = rpc->outqueue.head) != NULL) { pdu->cb(rpc, RPC_STATUS_ERROR, (void *)error, pdu->private_data); rpc->outqueue.head = pdu->next; rpc_free_pdu(rpc, pdu); } rpc->outqueue.tail = NULL; for (i = 0; i < HASHES; i++) { struct rpc_queue *q = &rpc->waitpdu[i]; while((pdu = q->head) != NULL) { pdu->cb(rpc, RPC_STATUS_ERROR, (void *)error, pdu->private_data); q->head = pdu->next; rpc_free_pdu(rpc, pdu); } q->tail = NULL; } } static void rpc_free_fragment(struct rpc_fragment *fragment) { if (fragment->data != NULL) { free(fragment->data); } free(fragment); } void rpc_free_all_fragments(struct rpc_context *rpc) { assert(rpc->magic == RPC_CONTEXT_MAGIC); while (rpc->fragments != NULL) { struct rpc_fragment *fragment = rpc->fragments; rpc->fragments = fragment->next; rpc_free_fragment(fragment); } } int rpc_add_fragment(struct rpc_context *rpc, char *data, uint64_t size) { struct rpc_fragment *fragment; assert(rpc->magic == RPC_CONTEXT_MAGIC); fragment = malloc(sizeof(struct rpc_fragment)); if (fragment == NULL) { return -1; } fragment->size = size; fragment->data = malloc(fragment->size); if(fragment->data == NULL) { free(fragment); return -1; } memcpy(fragment->data, data, fragment->size); LIBNFS_LIST_ADD_END(&rpc->fragments, fragment); return 0; } void rpc_destroy_context(struct rpc_context *rpc) { struct rpc_pdu *pdu; unsigned int i; assert(rpc->magic == RPC_CONTEXT_MAGIC); while((pdu = rpc->outqueue.head) != NULL) { pdu->cb(rpc, RPC_STATUS_CANCEL, NULL, pdu->private_data); LIBNFS_LIST_REMOVE(&rpc->outqueue.head, pdu); rpc_free_pdu(rpc, pdu); } for (i = 0; i < HASHES; i++) { struct rpc_queue *q = &rpc->waitpdu[i]; while((pdu = q->head) != NULL) { pdu->cb(rpc, RPC_STATUS_CANCEL, NULL, pdu->private_data); LIBNFS_LIST_REMOVE(&q->head, pdu); rpc_free_pdu(rpc, pdu); } } rpc_free_all_fragments(rpc); auth_destroy(rpc->auth); rpc->auth =NULL; if (rpc->fd != -1) { close(rpc->fd); } free(rpc->encodebuf); free(rpc->inbuf); free(rpc->error_string); free(rpc->udp_dest); rpc->magic = 0; free(rpc); } libnfs-libnfs-1.9.8/lib/libnfs-sync.c000066400000000000000000001074241255745034100174400ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ /* * High level api to nfs filesystems */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NET_IF_H #include #endif #ifdef ANDROID #define statvfs statfs #endif #ifdef HAVE_SYS_VFS_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #include #include #include #include #include #include #include #include #ifdef HAVE_SYS_SOCKIO_H #include #endif #ifdef HAVE_SYS_TIME_H #include #endif #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" #include "libnfs-raw-nfs.h" #include "libnfs-private.h" struct sync_cb_data { int is_finished; int status; uint64_t offset; void *return_data; int return_int; const char *call; }; static void wait_for_reply(struct rpc_context *rpc, struct sync_cb_data *cb_data) { struct pollfd pfd; assert(rpc->magic == RPC_CONTEXT_MAGIC); while (!cb_data->is_finished) { pfd.fd = rpc_get_fd(rpc); pfd.events = rpc_which_events(rpc); if (poll(&pfd, 1, -1) < 0) { rpc_set_error(rpc, "Poll failed"); cb_data->status = -EIO; break; } if (rpc_service(rpc, pfd.revents) < 0) { rpc_set_error(rpc, "rpc_service failed"); cb_data->status = -EIO; break; } if (rpc_get_fd(rpc) == -1) { rpc_set_error(rpc, "Socket closed\n"); break; } } } static void wait_for_nfs_reply(struct nfs_context *nfs, struct sync_cb_data *cb_data) { struct pollfd pfd; while (!cb_data->is_finished) { pfd.fd = nfs_get_fd(nfs); pfd.events = nfs_which_events(nfs); if (poll(&pfd, 1, -1) < 0) { nfs_set_error(nfs, "Poll failed"); cb_data->status = -EIO; break; } if (nfs_service(nfs, pfd.revents) < 0) { nfs_set_error(nfs, "nfs_service failed"); cb_data->status = -EIO; break; } } } /* * connect to the server and mount the export */ static void mount_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "mount/mnt call failed with \"%s\"", (char *)data); return; } } int nfs_mount(struct nfs_context *nfs, const char *server, const char *export) { struct sync_cb_data cb_data; struct rpc_context *rpc = nfs_get_rpc_context(nfs); assert(rpc->magic == RPC_CONTEXT_MAGIC); cb_data.is_finished = 0; if (nfs_mount_async(nfs, server, export, mount_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_mount_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); /* Dont want any more callbacks even if the socket is closed */ rpc->connect_cb = NULL; return cb_data.status; } /* * stat() */ static void stat_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "stat call failed with \"%s\"", (char *)data); return; } #ifdef WIN32 memcpy(cb_data->return_data, data, sizeof(struct __stat64)); #else memcpy(cb_data->return_data, data, sizeof(struct stat)); #endif } #ifdef WIN32 int nfs_stat(struct nfs_context *nfs, const char *path, struct __stat64 *st) #else int nfs_stat(struct nfs_context *nfs, const char *path, struct stat *st) #endif { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = st; if (nfs_stat_async(nfs, path, stat_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_stat_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } static void stat64_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "stat call failed with \"%s\"", (char *)data); return; } memcpy(cb_data->return_data, data, sizeof(struct nfs_stat_64)); } int nfs_stat64(struct nfs_context *nfs, const char *path, struct nfs_stat_64 *st) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = st; if (nfs_stat64_async(nfs, path, stat64_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_stat64_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } int nfs_lstat64(struct nfs_context *nfs, const char *path, struct nfs_stat_64 *st) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = st; if (nfs_lstat64_async(nfs, path, stat64_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_lstat64_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * open() */ static void open_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; struct nfsfh *fh, **nfsfh; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "open call failed with \"%s\"", (char *)data); return; } fh = data; nfsfh = cb_data->return_data; *nfsfh = fh; } int nfs_open(struct nfs_context *nfs, const char *path, int flags, struct nfsfh **nfsfh) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = nfsfh; if (nfs_open_async(nfs, path, flags, open_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_open_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * chdir() */ static void chdir_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "chdir call failed with \"%s\"", (char *)data); return; } } int nfs_chdir(struct nfs_context *nfs, const char *path) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_chdir_async(nfs, path, chdir_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_chdir_async failed with %s", nfs_get_error(nfs)); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * pread() */ static void pread_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; char *buffer; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "%s call failed with \"%s\"", cb_data->call, (char *)data); return; } buffer = cb_data->return_data; memcpy(buffer, (char *)data, status); } int nfs_pread(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buffer) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = buffer; cb_data.call = "pread"; if (nfs_pread_async(nfs, nfsfh, offset, count, pread_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_pread_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * read() */ int nfs_read(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buffer) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = buffer; cb_data.call = "read"; if (nfs_read_async(nfs, nfsfh, count, pread_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_read_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * close() */ static void close_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "close call failed with \"%s\"", (char *)data); return; } } int nfs_close(struct nfs_context *nfs, struct nfsfh *nfsfh) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_close_async(nfs, nfsfh, close_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_close_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * fstat() */ int nfs_fstat(struct nfs_context *nfs, struct nfsfh *nfsfh, struct stat *st) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = st; if (nfs_fstat_async(nfs, nfsfh, stat_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_fstat_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * fstat64() */ int nfs_fstat64(struct nfs_context *nfs, struct nfsfh *nfsfh, struct nfs_stat_64 *st) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = st; if (nfs_fstat64_async(nfs, nfsfh, stat64_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_fstat64_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * pwrite() */ static void pwrite_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) nfs_set_error(nfs, "%s call failed with \"%s\"", cb_data->call, (char *)data); } int nfs_pwrite(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.call = "pwrite"; if (nfs_pwrite_async(nfs, nfsfh, offset, count, buf, pwrite_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_pwrite_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * write() */ int nfs_write(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.call = "write"; if (nfs_write_async(nfs, nfsfh, count, buf, pwrite_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_write_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * fsync() */ static void fsync_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "fsync call failed with \"%s\"", (char *)data); return; } } int nfs_fsync(struct nfs_context *nfs, struct nfsfh *nfsfh) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_fsync_async(nfs, nfsfh, fsync_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_fsync_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * ftruncate() */ static void ftruncate_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "ftruncate call failed with \"%s\"", (char *)data); return; } } int nfs_ftruncate(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_ftruncate_async(nfs, nfsfh, length, ftruncate_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_ftruncate_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * truncate() */ static void truncate_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "truncate call failed with \"%s\"", (char *)data); return; } } int nfs_truncate(struct nfs_context *nfs, const char *path, uint64_t length) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_truncate_async(nfs, path, length, truncate_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_ftruncate_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * mkdir() */ static void mkdir_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "mkdir call failed with \"%s\"", (char *)data); return; } } int nfs_mkdir(struct nfs_context *nfs, const char *path) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_mkdir_async(nfs, path, mkdir_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_mkdir_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * rmdir() */ static void rmdir_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "rmdir call failed with \"%s\"", (char *)data); return; } } int nfs_rmdir(struct nfs_context *nfs, const char *path) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_rmdir_async(nfs, path, rmdir_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_rmdir_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * creat() */ static void creat_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; struct nfsfh *fh, **nfsfh; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "creat call failed with \"%s\"", (char *)data); return; } fh = data; nfsfh = cb_data->return_data; *nfsfh = fh; } int nfs_create(struct nfs_context *nfs, const char *path, int flags, int mode, struct nfsfh **nfsfh) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = nfsfh; if (nfs_create_async(nfs, path, flags, mode, creat_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_create_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } int nfs_creat(struct nfs_context *nfs, const char *path, int mode, struct nfsfh **nfsfh) { return nfs_create(nfs, path, 0, mode, nfsfh); } /* * mknod() */ static void mknod_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "mknod call failed with \"%s\"", (char *)data); return; } } int nfs_mknod(struct nfs_context *nfs, const char *path, int mode, int dev) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_mknod_async(nfs, path, mode, dev, mknod_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_creat_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * unlink() */ static void unlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "unlink call failed with \"%s\"", (char *)data); return; } } int nfs_unlink(struct nfs_context *nfs, const char *path) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_unlink_async(nfs, path, unlink_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_unlink_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * opendir() */ static void opendir_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; struct nfsdir *dir, **nfsdir; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "opendir call failed with \"%s\"", (char *)data); return; } dir = data; nfsdir = cb_data->return_data; *nfsdir = dir; } int nfs_opendir(struct nfs_context *nfs, const char *path, struct nfsdir **nfsdir) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = nfsdir; if (nfs_opendir_async(nfs, path, opendir_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_opendir_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * lseek() */ static void lseek_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "lseek call failed with \"%s\"", (char *)data); return; } if (cb_data->return_data != NULL) { memcpy(cb_data->return_data, data, sizeof(uint64_t)); } } int nfs_lseek(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset, int whence, uint64_t *current_offset) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = current_offset; if (nfs_lseek_async(nfs, nfsfh, offset, whence, lseek_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_lseek_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * statvfs() */ static void statvfs_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "statvfs call failed with \"%s\"", (char *)data); return; } memcpy(cb_data->return_data, data, sizeof(struct statvfs)); } int nfs_statvfs(struct nfs_context *nfs, const char *path, struct statvfs *svfs) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = svfs; if (nfs_statvfs_async(nfs, path, statvfs_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_statvfs_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * readlink() */ static void readlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "readlink call failed with \"%s\"", (char *)data); return; } if (strlen(data) > (size_t)cb_data->return_int) { nfs_set_error(nfs, "Too small buffer for readlink"); cb_data->status = -ENAMETOOLONG; return; } memcpy(cb_data->return_data, data, strlen(data)+1); } int nfs_readlink(struct nfs_context *nfs, const char *path, char *buf, int bufsize) { struct sync_cb_data cb_data; cb_data.is_finished = 0; cb_data.return_data = buf; cb_data.return_int = bufsize; if (nfs_readlink_async(nfs, path, readlink_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_readlink_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * chmod() */ static void chmod_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "chmod call failed with \"%s\"", (char *)data); return; } } int nfs_chmod(struct nfs_context *nfs, const char *path, int mode) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_chmod_async(nfs, path, mode, chmod_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_chmod_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } int nfs_lchmod(struct nfs_context *nfs, const char *path, int mode) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_lchmod_async(nfs, path, mode, chmod_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_lchmod_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * fchmod() */ static void fchmod_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "fchmod call failed with \"%s\"", (char *)data); return; } } int nfs_fchmod(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_fchmod_async(nfs, nfsfh, mode, fchmod_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_fchmod_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * chown() */ static void chown_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "chown call failed with \"%s\"", (char *)data); return; } } int nfs_chown(struct nfs_context *nfs, const char *path, int uid, int gid) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_chown_async(nfs, path, uid, gid, chown_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_chown_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * lchown() */ int nfs_lchown(struct nfs_context *nfs, const char *path, int uid, int gid) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_lchown_async(nfs, path, uid, gid, chown_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_lchown_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * fchown() */ static void fchown_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "fchown call failed with \"%s\"", (char *)data); return; } } int nfs_fchown(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_fchown_async(nfs, nfsfh, uid, gid, fchown_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_fchown_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * utimes() */ static void utimes_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "utimes call failed with \"%s\"", (char *)data); return; } } int nfs_utimes(struct nfs_context *nfs, const char *path, struct timeval *times) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_utimes_async(nfs, path, times, utimes_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_utimes_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } int nfs_lutimes(struct nfs_context *nfs, const char *path, struct timeval *times) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_lutimes_async(nfs, path, times, utimes_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_lutimes_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * utime() */ static void utime_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "utime call failed with \"%s\"", (char *)data); return; } } int nfs_utime(struct nfs_context *nfs, const char *path, struct utimbuf *times) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_utime_async(nfs, path, times, utime_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_utimes_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * access() */ static void access_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "access call failed with \"%s\"", (char *)data); return; } } int nfs_access(struct nfs_context *nfs, const char *path, int mode) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_access_async(nfs, path, mode, access_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_access_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * access2() */ static void access2_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "access2 call failed with \"%s\"", (char *)data); return; } } int nfs_access2(struct nfs_context *nfs, const char *path) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_access2_async(nfs, path, access2_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_access2_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * symlink() */ static void symlink_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "symlink call failed with \"%s\"", (char *)data); return; } } int nfs_symlink(struct nfs_context *nfs, const char *oldpath, const char *newpath) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_symlink_async(nfs, oldpath, newpath, symlink_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_symlink_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * rename() */ static void rename_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "rename call failed with \"%s\"", (char *)data); return; } } int nfs_rename(struct nfs_context *nfs, const char *oldpath, const char *newpath) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_rename_async(nfs, oldpath, newpath, rename_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_rename_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } /* * link() */ static void link_cb(int status, struct nfs_context *nfs, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; cb_data->is_finished = 1; cb_data->status = status; if (status < 0) { nfs_set_error(nfs, "link call failed with \"%s\"", (char *)data); return; } } int nfs_link(struct nfs_context *nfs, const char *oldpath, const char *newpath) { struct sync_cb_data cb_data; cb_data.is_finished = 0; if (nfs_link_async(nfs, oldpath, newpath, link_cb, &cb_data) != 0) { nfs_set_error(nfs, "nfs_link_async failed"); return -1; } wait_for_nfs_reply(nfs, &cb_data); return cb_data.status; } void mount_getexports_cb(struct rpc_context *mount_context, int status, void *data, void *private_data) { struct sync_cb_data *cb_data = private_data; exports export; assert(mount_context->magic == RPC_CONTEXT_MAGIC); cb_data->is_finished = 1; cb_data->status = status; cb_data->return_data = NULL; if (status != 0) { rpc_set_error(mount_context, "mount/export call failed with \"%s\"", (char *)data); return; } export = *(exports *)data; while (export != NULL) { exports new_export; new_export = malloc(sizeof(*new_export)); memset(new_export, 0, sizeof(*new_export)); new_export->ex_dir = strdup(export->ex_dir); new_export->ex_next = cb_data->return_data; cb_data->return_data = new_export; export = export->ex_next; } } struct exportnode *mount_getexports(const char *server) { struct sync_cb_data cb_data; struct rpc_context *rpc; cb_data.is_finished = 0; cb_data.return_data = NULL; rpc = rpc_init_context(); if (mount_getexports_async(rpc, server, mount_getexports_cb, &cb_data) != 0) { rpc_destroy_context(rpc); return NULL; } wait_for_reply(rpc, &cb_data); rpc_destroy_context(rpc); return cb_data.return_data; } void mount_free_export_list(struct exportnode *exp) { struct exportnode *tmp; while ((tmp = exp)) { exp = exp->ex_next; free(tmp->ex_dir); free(tmp); } } void free_nfs_srvr_list(struct nfs_server_list *srv) { while (srv != NULL) { struct nfs_server_list *next = srv->next; free(srv->addr); free(srv); srv = next; } } struct nfs_list_data { int status; struct nfs_server_list *srvrs; }; void callit_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) { struct nfs_list_data *srv_data = private_data; struct sockaddr *sin; char hostdd[16]; struct nfs_server_list *srvr; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_CANCEL) { return; } if (status != 0) { srv_data->status = -1; return; } sin = rpc_get_recv_sockaddr(rpc); if (sin == NULL) { rpc_set_error(rpc, "failed to get sockaddr in CALLIT callback"); srv_data->status = -1; return; } if (getnameinfo(sin, sizeof(struct sockaddr_in), &hostdd[0], sizeof(hostdd), NULL, 0, NI_NUMERICHOST) < 0) { rpc_set_error(rpc, "getnameinfo failed in CALLIT callback"); srv_data->status = -1; return; } /* check for dupes */ for (srvr = srv_data->srvrs; srvr; srvr = srvr->next) { if (!strcmp(hostdd, srvr->addr)) { return; } } srvr = malloc(sizeof(struct nfs_server_list)); if (srvr == NULL) { rpc_set_error(rpc, "Malloc failed when allocating server structure"); srv_data->status = -1; return; } srvr->addr = strdup(hostdd); if (srvr->addr == NULL) { rpc_set_error(rpc, "Strdup failed when allocating server structure"); free(srvr); srv_data->status = -1; return; } srvr->next = srv_data->srvrs; srv_data->srvrs = srvr; } #ifdef WIN32 static int send_nfsd_probes(struct rpc_context *rpc, INTERFACE_INFO *InterfaceList, int numIfs, struct nfs_list_data *data) { int i=0; assert(rpc->magic == RPC_CONTEXT_MAGIC); for(i = 0; i < numIfs; i++) { SOCKADDR *pAddress; char bcdd[16]; unsigned long nFlags = 0; pAddress = (SOCKADDR *) & (InterfaceList[i].iiBroadcastAddress); if(pAddress->sa_family != AF_INET) continue; nFlags = InterfaceList[i].iiFlags; if (!(nFlags & IFF_UP)) { continue; } if (nFlags & IFF_LOOPBACK) { continue; } if (!(nFlags & IFF_BROADCAST)) { continue; } if (getnameinfo(pAddress, sizeof(struct sockaddr_in), &bcdd[0], sizeof(bcdd), NULL, 0, NI_NUMERICHOST) < 0) { continue; } if (rpc_set_udp_destination(rpc, bcdd, 111, 1) < 0) { return -1; } if (rpc_pmap2_callit_async(rpc, MOUNT_PROGRAM, 2, 0, NULL, 0, callit_cb, data) < 0) { return -1; } } return 0; } struct nfs_server_list *nfs_find_local_servers(void) { struct rpc_context *rpc; struct nfs_list_data data = {0, NULL}; struct timeval tv_start, tv_current; int loop; struct pollfd pfd; INTERFACE_INFO InterfaceList[20]; unsigned long nBytesReturned; int nNumInterfaces = 0; rpc = rpc_init_udp_context(); if (rpc == NULL) { return NULL; } if (rpc_bind_udp(rpc, "0.0.0.0", 0) < 0) { rpc_destroy_context(rpc); return NULL; } if (WSAIoctl(rpc_get_fd(rpc), SIO_GET_INTERFACE_LIST, 0, 0, &InterfaceList, sizeof(InterfaceList), &nBytesReturned, 0, 0) == SOCKET_ERROR) { return NULL; } nNumInterfaces = nBytesReturned / sizeof(INTERFACE_INFO); for (loop=0; loop<3; loop++) { if (send_nfsd_probes(rpc, InterfaceList, nNumInterfaces, &data) != 0) { rpc_destroy_context(rpc); return NULL; } win32_gettimeofday(&tv_start, NULL); for(;;) { int mpt; pfd.fd = rpc_get_fd(rpc); pfd.events = rpc_which_events(rpc); win32_gettimeofday(&tv_current, NULL); mpt = 1000 - (tv_current.tv_sec *1000 + tv_current.tv_usec / 1000) + (tv_start.tv_sec *1000 + tv_start.tv_usec / 1000); if (poll(&pfd, 1, mpt) < 0) { free_nfs_srvr_list(data.srvrs); rpc_destroy_context(rpc); return NULL; } if (pfd.revents == 0) { break; } if (rpc_service(rpc, pfd.revents) < 0) { break; } } } rpc_destroy_context(rpc); if (data.status != 0) { free_nfs_srvr_list(data.srvrs); return NULL; } return data.srvrs; } #else static int send_nfsd_probes(struct rpc_context *rpc, struct ifconf *ifc, struct nfs_list_data *data) { char *ptr; assert(rpc->magic == RPC_CONTEXT_MAGIC); for (ptr =(char *)(ifc->ifc_buf); ptr < (char *)(ifc->ifc_buf) + ifc->ifc_len; ) { struct ifreq *ifr; char bcdd[16]; ifr = (struct ifreq *)ptr; #ifdef HAVE_SOCKADDR_LEN if (ifr->ifr_addr.sa_len > sizeof(struct sockaddr)) { ptr += sizeof(ifr->ifr_name) + ifr->ifr_addr.sa_len; } else { ptr += sizeof(ifr->ifr_name) + sizeof(struct sockaddr); } #else ptr += sizeof(struct ifreq); #endif if (ifr->ifr_addr.sa_family != AF_INET) { continue; } if (ioctl(rpc_get_fd(rpc), SIOCGIFFLAGS, ifr) < 0) { return -1; } if (!(ifr->ifr_flags & IFF_UP)) { continue; } if (ifr->ifr_flags & IFF_LOOPBACK) { continue; } if (!(ifr->ifr_flags & IFF_BROADCAST)) { continue; } if (ioctl(rpc_get_fd(rpc), SIOCGIFBRDADDR, ifr) < 0) { continue; } if (getnameinfo(&ifr->ifr_broadaddr, sizeof(struct sockaddr_in), &bcdd[0], sizeof(bcdd), NULL, 0, NI_NUMERICHOST) < 0) { continue; } if (rpc_set_udp_destination(rpc, bcdd, 111, 1) < 0) { return -1; } if (rpc_pmap2_callit_async(rpc, MOUNT_PROGRAM, 2, 0, NULL, 0, callit_cb, data) < 0) { return -1; } } return 0; } struct nfs_server_list *nfs_find_local_servers(void) { struct rpc_context *rpc; struct nfs_list_data data = {0, NULL}; struct timeval tv_start, tv_current; struct ifconf ifc; int size, loop; struct pollfd pfd; rpc = rpc_init_udp_context(); if (rpc == NULL) { return NULL; } if (rpc_bind_udp(rpc, "0.0.0.0", 0) < 0) { rpc_destroy_context(rpc); return NULL; } /* get list of all interfaces */ size = sizeof(struct ifreq); ifc.ifc_buf = NULL; ifc.ifc_len = size; while(ifc.ifc_len > (size - sizeof(struct ifreq))) { size *= 2; free(ifc.ifc_buf); ifc.ifc_len = size; ifc.ifc_buf = malloc(size); memset(ifc.ifc_buf, 0, size); if (ioctl(rpc_get_fd(rpc), SIOCGIFCONF, (caddr_t)&ifc) < 0) { rpc_destroy_context(rpc); free(ifc.ifc_buf); return NULL; } } for (loop=0; loop<3; loop++) { if (send_nfsd_probes(rpc, &ifc, &data) != 0) { rpc_destroy_context(rpc); free(ifc.ifc_buf); return NULL; } gettimeofday(&tv_start, NULL); for(;;) { int mpt; pfd.fd = rpc_get_fd(rpc); pfd.events = rpc_which_events(rpc); gettimeofday(&tv_current, NULL); mpt = 1000 - (tv_current.tv_sec *1000 + tv_current.tv_usec / 1000) + (tv_start.tv_sec *1000 + tv_start.tv_usec / 1000); if (poll(&pfd, 1, mpt) < 0) { free_nfs_srvr_list(data.srvrs); rpc_destroy_context(rpc); return NULL; } if (pfd.revents == 0) { break; } if (rpc_service(rpc, pfd.revents) < 0) { break; } } } free(ifc.ifc_buf); rpc_destroy_context(rpc); if (data.status != 0) { free_nfs_srvr_list(data.srvrs); return NULL; } return data.srvrs; } #endif//WIN32 libnfs-libnfs-1.9.8/lib/libnfs-win32.def000066400000000000000000000075371255745034100177460ustar00rootroot00000000000000LIBRARY libnfs EXPORTS mount_free_export_list mount_getexports mount_getexports_async nfs_find_local_servers free_nfs_srvr_list nfs_access nfs_access_async nfs_chdir nfs_chmod nfs_chmod_async nfs_chown nfs_chown_async nfs_close nfs_close_async nfs_closedir nfs_creat nfs_creat_async nfs_destroy_context nfs_fchmod nfs_fchmod_async nfs_fchown nfs_fchown_async nfs_fstat nfs_fstat_async nfs_fsync nfs_fsync_async nfs_ftruncate nfs_ftruncate_async nfs_get_error nfs_get_fd nfs_get_readmax nfs_get_writemax nfs_getcwd nfs_init_context nfs_link nfs_link_async nfs_lseek nfs_lseek_async nfs_mkdir nfs_mkdir_async nfs_mknod nfs_mknod_async nfs_mount nfs_mount_async nfs_open nfs_open_async nfs_opendir nfs_opendir_async nfs_parse_url_full nfs_parse_url_dir nfs_parse_url_incomplete nfs_destroy_url nfs_pread nfs_pread_async nfs_pwrite nfs_pwrite_async nfs_read nfs_read_async nfs_readdir nfs_readlink nfs_readlink_async nfs_rename nfs_rename_async nfs_rmdir nfs_rmdir_async nfs_service nfs_set_auth nfs_set_gid nfs_set_tcp_syncnt nfs_set_uid nfs_set_readahead nfs_set_debug nfs_stat nfs_stat_async nfs_stat64 nfs_stat64_async nfs_statvfs nfs_statvfs_async nfs_symlink nfs_symlink_async nfs_truncate nfs_truncate_async nfs_unlink nfs_unlink_async nfs_utime nfs_utime_async nfs_utimes nfs_utimes_async nfs_which_events nfs_write nfs_write_async win32_poll rpc_connect_async rpc_destroy_context rpc_disconnect rpc_get_error rpc_get_fd rpc_init_context rpc_pmap2_null_async rpc_pmap2_getport_async rpc_pmap2_set_async rpc_pmap2_unset_async rpc_pmap2_dump_async rpc_pmap2_callit_async rpc_pmap3_null_async rpc_pmap3_set_async rpc_pmap3_unset_async rpc_pmap3_getaddr_async rpc_pmap3_dump_async rpc_pmap3_callit_async rpc_pmap3_gettime_async rpc_pmap3_uaddr2taddr_async rpc_pmap3_taddr2uaddr_async rpc_mount_null_async rpc_mount_mnt_async rpc_mount_dump_async rpc_mount_umnt_async rpc_mount_umntall_async rpc_mount_export_async rpc_mount1_null_async rpc_mount1_mnt_async rpc_mount1_dump_async rpc_mount1_umnt_async rpc_mount1_umntall_async rpc_mount1_export_async rpc_mount3_null_async rpc_mount3_mnt_async rpc_mount3_dump_async rpc_mount3_umnt_async rpc_mount3_umntall_async rpc_mount3_export_async rpc_nfsacl_null_async rpc_nfsacl_getacl_async rpc_nfsacl_setacl_async rpc_nfs_null_async rpc_nfs_getattr_async rpc_nfs_pathconf_async rpc_nfs_lookup_async rpc_nfs_access_async rpc_nfs_read_async rpc_nfs_write_async rpc_nfs_commit_async rpc_nfs_setattr_async rpc_nfs_mkdir_async rpc_nfs_rmdir_async rpc_nfs_create_async rpc_nfs_mknod_async rpc_nfs_remove_async rpc_nfs_readdir_async rpc_nfs_readdirplus_async rpc_nfs_fsstat_async rpc_nfs_fsinfo_async rpc_nfs_readlink_async rpc_nfs_symlink_async rpc_nfs_rename_async rpc_nfs_link_async rpc_nfs2_null_async rpc_nfs2_getattr_async rpc_nfs2_setattr_async rpc_nfs2_lookup_async rpc_nfs2_readlink_async rpc_nfs2_read_async rpc_nfs2_write_async rpc_nfs2_create_async rpc_nfs2_remove_async rpc_nfs2_rename_async rpc_nfs2_link_async rpc_nfs2_symlink_async rpc_nfs2_mkdir_async rpc_nfs2_rmdir_async rpc_nfs2_readdir_async rpc_nfs2_statfs_async rpc_nfs3_null_async rpc_nfs3_getattr_async rpc_nfs3_pathconf_async rpc_nfs3_lookup_async rpc_nfs3_access_async rpc_nfs3_read_async rpc_nfs3_write_async rpc_nfs3_commit_async rpc_nfs3_setattr_async rpc_nfs3_mkdir_async rpc_nfs3_rmdir_async rpc_nfs3_create_async rpc_nfs3_mknod_async rpc_nfs3_remove_async rpc_nfs3_readdir_async rpc_nfs3_readdirplus_async rpc_nfs3_fsstat_async rpc_nfs3_fsinfo_async rpc_nfs3_readlink_async rpc_nfs3_symlink_async rpc_nfs3_rename_async rpc_nfs3_link_async rpc_nlm4_null_async rpc_nlm4_test_async rpc_nlm4_lock_async rpc_nlm4_cancel_async rpc_nlm4_unlock_async rpc_nsm1_null_async rpc_nsm1_stat_async rpc_nsm1_mon_async rpc_nsm1_unmon_async rpc_nsm1_unmonall_async rpc_nsm1_simucrash_async rpc_nsm1_notify_async rpc_rquota1_null_async rpc_rquota1_getquota_async rpc_rquota1_getactivequota_async rpc_service rpc_set_fd rpc_which_events libnfs-libnfs-1.9.8/lib/libnfs-zdr.c000066400000000000000000000276201255745034100172620ustar00rootroot00000000000000/* Copyright (C) 2012 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ /* * This file contains definitions for the built in ZDR implementation. * This is a very limited ZDR subset that can only marshal to/from a momory buffer, * i.e. zdrmem_create() buffers. * It aims to be compatible with normal rpcgen generated functions. */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef WIN32 #include "win32_compat.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef HAVE_ARPA_INET_H #include #endif #include #include #include #include #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" struct opaque_auth _null_auth; bool_t libnfs_zdr_setpos(ZDR *zdrs, uint32_t pos) { zdrs->pos = pos; return TRUE; } uint32_t libnfs_zdr_getpos(ZDR *zdrs) { return zdrs->pos; } void libnfs_zdrmem_create(ZDR *zdrs, const caddr_t addr, uint32_t size, enum zdr_op xop) { zdrs->x_op = xop; zdrs->buf = addr; zdrs->size = size; zdrs->pos = 0; zdrs->mem = NULL; } static void *zdr_malloc(ZDR *zdrs, uint32_t size) { struct zdr_mem *mem; mem = malloc(sizeof(struct zdr_mem)); mem->next = zdrs->mem; mem->size = size; mem->buf = malloc(mem->size); zdrs->mem = mem; return mem->buf; } void libnfs_zdr_destroy(ZDR *zdrs) { while (zdrs->mem != NULL) { struct zdr_mem *mem = zdrs->mem->next; free(zdrs->mem->buf); free(zdrs->mem); zdrs->mem = mem; } } bool_t libnfs_zdr_u_int(ZDR *zdrs, uint32_t *u) { if (zdrs->pos + 4 > zdrs->size) { return FALSE; } switch (zdrs->x_op) { case ZDR_ENCODE: *(uint32_t *)&zdrs->buf[zdrs->pos] = htonl(*u); zdrs->pos += 4; return TRUE; break; case ZDR_DECODE: *u = ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]); zdrs->pos += 4; return TRUE; break; } return FALSE; } bool_t libnfs_zdr_int(ZDR *zdrs, int32_t *i) { return libnfs_zdr_u_int(zdrs, (uint32_t *)i); } bool_t libnfs_zdr_uint64_t(ZDR *zdrs, uint64_t *u) { if (zdrs->pos + 8 > zdrs->size) { return FALSE; } switch (zdrs->x_op) { case ZDR_ENCODE: *(uint32_t *)&zdrs->buf[zdrs->pos] = htonl((*u >> 32)); zdrs->pos += 4; *(uint32_t *)&zdrs->buf[zdrs->pos] = htonl((*u & 0xffffffff)); zdrs->pos += 4; return TRUE; break; case ZDR_DECODE: *u = ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]); zdrs->pos += 4; *u <<= 32; *u |= (uint32_t)ntohl(*(uint32_t *)&zdrs->buf[zdrs->pos]); zdrs->pos += 4; return TRUE; break; } return FALSE; } bool_t libnfs_zdr_int64_t(ZDR *zdrs, int64_t *i) { return libnfs_zdr_uint64_t(zdrs, (uint64_t *)i); } bool_t libnfs_zdr_bytes(ZDR *zdrs, char **bufp, uint32_t *size, uint32_t maxsize) { if (!libnfs_zdr_u_int(zdrs, size)) { return FALSE; } if (zdrs->pos + *size > zdrs->size) { return FALSE; } switch (zdrs->x_op) { case ZDR_ENCODE: memcpy(&zdrs->buf[zdrs->pos], *bufp, *size); zdrs->pos += *size; zdrs->pos = (zdrs->pos + 3) & ~3; return TRUE; case ZDR_DECODE: if (*bufp == NULL) { *bufp = zdr_malloc(zdrs, *size); } memcpy(*bufp, &zdrs->buf[zdrs->pos], *size); zdrs->pos += *size; zdrs->pos = (zdrs->pos + 3) & ~3; return TRUE; } return FALSE; } bool_t libnfs_zdr_enum(ZDR *zdrs, enum_t *e) { bool_t ret; int32_t i = *e; ret = libnfs_zdr_u_int(zdrs, (uint32_t *)&i); *e = i; return ret; } bool_t libnfs_zdr_bool(ZDR *zdrs, bool_t *b) { return libnfs_zdr_u_int(zdrs, (uint32_t *)b); } bool_t libnfs_zdr_void(void) { return TRUE; } bool_t libnfs_zdr_pointer(ZDR *zdrs, char **objp, uint32_t size, zdrproc_t proc) { bool_t more_data; more_data = (*objp != NULL); if (!libnfs_zdr_bool(zdrs, &more_data)) { return FALSE; } if (more_data == 0) { *objp = NULL; return TRUE; } if (zdrs->x_op == ZDR_DECODE) { *objp = zdr_malloc(zdrs, size); if (*objp == NULL) { return FALSE; } memset(*objp, 0, size); } return proc(zdrs, *objp); } bool_t libnfs_zdr_opaque(ZDR *zdrs, char *objp, uint32_t size) { switch (zdrs->x_op) { case ZDR_ENCODE: memcpy(&zdrs->buf[zdrs->pos], objp, size); zdrs->pos += size; if (zdrs->pos & 3) { memset(&zdrs->buf[zdrs->pos], 0x00, 4 - (zdrs->pos & 3)); } zdrs->pos = (zdrs->pos + 3) & ~3; return TRUE; case ZDR_DECODE: memcpy(objp, &zdrs->buf[zdrs->pos], size); zdrs->pos += size; zdrs->pos = (zdrs->pos + 3) & ~3; return TRUE; } return FALSE; } bool_t libnfs_zdr_string(ZDR *zdrs, char **strp, uint32_t maxsize) { uint32_t size; if (zdrs->x_op == ZDR_ENCODE) { size = strlen(*strp); } if (!libnfs_zdr_u_int(zdrs, &size)) { return FALSE; } if (zdrs->pos + size > zdrs->size) { return FALSE; } switch (zdrs->x_op) { case ZDR_ENCODE: return libnfs_zdr_opaque(zdrs, *strp, size); case ZDR_DECODE: *strp = zdr_malloc(zdrs, size + 1); if (*strp == NULL) { return FALSE; } (*strp)[size] = 0; return libnfs_zdr_opaque(zdrs, *strp, size); } return FALSE; } bool_t libnfs_zdr_array(ZDR *zdrs, char **arrp, uint32_t *size, uint32_t maxsize, uint32_t elsize, zdrproc_t proc) { int i; if (!libnfs_zdr_u_int(zdrs, size)) { return FALSE; } if (zdrs->pos + *size * elsize > zdrs->size) { return FALSE; } if (zdrs->x_op == ZDR_DECODE) { *arrp = zdr_malloc(zdrs, *size * elsize); if (*arrp == NULL) { return FALSE; } memset(*arrp, 0, *size * elsize); } for (i = 0; i < *size; i++) { if (!proc(zdrs, *arrp + i * elsize)) { return FALSE; } } return TRUE; } void libnfs_zdr_free(zdrproc_t proc, char *objp) { } static bool_t libnfs_opaque_auth(ZDR *zdrs, struct opaque_auth *auth) { if (!libnfs_zdr_u_int(zdrs, &auth->oa_flavor)) { return FALSE; } if (!libnfs_zdr_bytes(zdrs, &auth->oa_base, &auth->oa_length, auth->oa_length)) { return FALSE; } return TRUE; } static bool_t libnfs_rpc_call_body(struct rpc_context *rpc, ZDR *zdrs, struct call_body *cmb) { if (!libnfs_zdr_u_int(zdrs, &cmb->rpcvers)) { rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " "RPCVERS"); return FALSE; } if (!libnfs_zdr_u_int(zdrs, &cmb->prog)) { rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " "PROG"); return FALSE; } if (!libnfs_zdr_u_int(zdrs, &cmb->vers)) { rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " "VERS"); return FALSE; } if (!libnfs_zdr_u_int(zdrs, &cmb->proc)) { rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " "PROC"); return FALSE; } if (!libnfs_opaque_auth(zdrs, &cmb->cred)) { rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " "CRED"); return FALSE; } if (!libnfs_opaque_auth(zdrs, &cmb->verf)) { rpc_set_error(rpc, "libnfs_rpc_call_body failed to encode " "VERF"); return FALSE; } return TRUE; } static bool_t libnfs_accepted_reply(ZDR *zdrs, struct accepted_reply *ar) { if (!libnfs_opaque_auth(zdrs, &ar->verf)) { return FALSE; } if (!libnfs_zdr_u_int(zdrs, &ar->stat)) { return FALSE; } switch (ar->stat) { case SUCCESS: if (!ar->reply_data.results.proc(zdrs, ar->reply_data.results.where)) { return FALSE; } return TRUE; case PROG_MISMATCH: if (!libnfs_zdr_u_int(zdrs, &ar->reply_data.mismatch_info.low)) { return FALSE; } if (!libnfs_zdr_u_int(zdrs, &ar->reply_data.mismatch_info.high)) { return FALSE; } return TRUE; default: return TRUE; } return FALSE; } static bool_t libnfs_rejected_reply(ZDR *zdrs, struct rejected_reply *rr) { if (!libnfs_zdr_u_int(zdrs, &rr->stat)) { return FALSE; } switch (rr->stat) { case RPC_MISMATCH: if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.mismatch_info.low)) { return FALSE; } if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.mismatch_info.high)) { return FALSE; } return TRUE; case AUTH_ERROR: if (!libnfs_zdr_u_int(zdrs, &rr->reject_data.stat)) { return FALSE; } return TRUE; default: return TRUE; } return FALSE; } static bool_t libnfs_rpc_reply_body(struct rpc_context *rpc, ZDR *zdrs, struct reply_body *rmb) { if (!libnfs_zdr_u_int(zdrs, &rmb->stat)) { rpc_set_error(rpc, "libnfs_rpc_reply_body failed to decode " "STAT"); return FALSE; } switch (rmb->stat) { case MSG_ACCEPTED: if (!libnfs_accepted_reply(zdrs, &rmb->reply.areply)) { rpc_set_error(rpc, "libnfs_rpc_reply_body failed to " "decode ACCEPTED"); return FALSE; } return TRUE; case MSG_DENIED: if (!libnfs_rejected_reply(zdrs, &rmb->reply.rreply)) { rpc_set_error(rpc, "libnfs_rpc_reply_body failed to " "decode DENIED"); return FALSE; } return TRUE; } rpc_set_error(rpc, "libnfs_rpc_reply_body failed to " "decode. Neither ACCEPTED nor DENIED"); return FALSE; } static bool_t libnfs_rpc_msg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg) { int ret; if (!libnfs_zdr_u_int(zdrs, &msg->xid)) { rpc_set_error(rpc, "libnfs_rpc_msg failed to decode XID"); return FALSE; } if (!libnfs_zdr_u_int(zdrs, &msg->direction)) { rpc_set_error(rpc, "libnfs_rpc_msg failed to decode DIRECTION"); return FALSE; } switch (msg->direction) { case CALL: ret = libnfs_rpc_call_body(rpc, zdrs, &msg->body.cbody); if (!ret) { rpc_set_error(rpc, "libnfs_rpc_msg failed to encode " "CALL, ret=%d: %s", ret, rpc_get_error(rpc)); } return ret; case REPLY: ret = libnfs_rpc_reply_body(rpc, zdrs, &msg->body.rbody); if (!ret) { rpc_set_error(rpc, "libnfs_rpc_msg failed to decode " "REPLY, ret=%d: %s", ret, rpc_get_error(rpc)); } return ret; default: rpc_set_error(rpc, "libnfs_rpc_msg failed to decode. " "Neither CALL not REPLY"); return FALSE; } } bool_t libnfs_zdr_callmsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg) { return libnfs_rpc_msg(rpc, zdrs, msg); } bool_t libnfs_zdr_replymsg(struct rpc_context *rpc, ZDR *zdrs, struct rpc_msg *msg) { return libnfs_rpc_msg(rpc, zdrs, msg); } struct AUTH *authnone_create(void) { struct AUTH *auth; auth = malloc(sizeof(struct AUTH)); auth->ah_cred.oa_flavor = AUTH_NONE; auth->ah_cred.oa_length = 0; auth->ah_cred.oa_base = NULL; auth->ah_verf.oa_flavor = AUTH_NONE; auth->ah_verf.oa_length = 0; auth->ah_verf.oa_base = NULL; auth->ah_private = NULL; return auth; } struct AUTH *libnfs_authunix_create(const char *host, uint32_t uid, uint32_t gid, uint32_t len, uint32_t *groups) { struct AUTH *auth; int size; uint32_t *buf; int idx; size = 4 + 4 + ((strlen(host) + 3) & ~3) + 4 + 4 + 4 + len * 4; auth = malloc(sizeof(struct AUTH)); memset(auth, 0x00, sizeof(struct AUTH)); auth->ah_cred.oa_flavor = AUTH_UNIX; auth->ah_cred.oa_length = size; auth->ah_cred.oa_base = malloc(size); memset(auth->ah_cred.oa_base, 0x00, size); buf = (uint32_t *)auth->ah_cred.oa_base; idx = 0; buf[idx++] = htonl(time(NULL)); buf[idx++] = htonl(strlen(host)); memcpy(&buf[2], host, strlen(host)); idx += (strlen(host) + 3) >> 2; buf[idx++] = htonl(uid); buf[idx++] = htonl(gid); buf[idx++] = htonl(len); while (len-- > 0) { buf[idx++] = htonl(*groups++); } auth->ah_verf.oa_flavor = AUTH_NONE; auth->ah_verf.oa_length = 0; auth->ah_verf.oa_base = NULL; auth->ah_private = NULL; return auth; } struct AUTH *libnfs_authunix_create_default(void) { #ifdef WIN32 return libnfs_authunix_create("libnfs", 65534, 65534, 0, NULL); #else return libnfs_authunix_create("libnfs", getuid(), getgid(), 0, NULL); #endif } void libnfs_auth_destroy(struct AUTH *auth) { if (auth->ah_cred.oa_base) { free(auth->ah_cred.oa_base); } if (auth->ah_verf.oa_base) { free(auth->ah_verf.oa_base); } free(auth); } libnfs-libnfs-1.9.8/lib/libnfs.c000066400000000000000000004501551255745034100164700ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ /* * High level api to nfs filesystems */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #endif #ifdef HAVE_UTIME_H #include #endif #ifdef ANDROID #define statvfs statfs #endif #define _GNU_SOURCE #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_VFS_H #include #endif #ifdef HAVE_SYS_STATVFS_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #ifdef MAJOR_IN_MKDEV #include #endif #ifdef MAJOR_IN_SYSMACROS #include #endif #include #include #include #include #include #include #include #include #include #include #include "libnfs-zdr.h" #include "slist.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" #include "libnfs-raw-nfs.h" #include "libnfs-raw-portmap.h" #include "libnfs-private.h" #define MAX_DIR_CACHE 128 #define MAX_LINK_COUNT 40 struct nfsdir { struct nfs_fh3 fh; fattr3 attr; struct nfsdir *next; struct nfsdirent *entries; struct nfsdirent *current; }; struct nfs_readahead { uint64_t fh_offset; uint64_t last_offset; uint64_t buf_offset; uint64_t buf_count; time_t buf_ts; char *buf; uint32_t cur_ra; }; struct nfsfh { struct nfs_fh3 fh; int is_sync; int is_append; uint64_t offset; struct nfs_readahead ra; }; struct nested_mounts { struct nested_mounts *next; char *path; struct nfs_fh3 fh; fattr3 attr; }; struct nfs_context { struct rpc_context *rpc; char *server; char *export; struct nfs_fh3 rootfh; uint64_t readmax; uint64_t writemax; char *cwd; struct nfsdir *dircache; uint16_t mask; int auto_traverse_mounts; struct nested_mounts *nested_mounts; }; void nfs_free_nfsdir(struct nfsdir *nfsdir) { while (nfsdir->entries) { struct nfsdirent *dirent = nfsdir->entries->next; if (nfsdir->entries->name != NULL) { free(nfsdir->entries->name); } free(nfsdir->entries); nfsdir->entries = dirent; } free(nfsdir->fh.data.data_val); free(nfsdir); } static void nfs_dircache_add(struct nfs_context *nfs, struct nfsdir *nfsdir) { int i; LIBNFS_LIST_ADD(&nfs->dircache, nfsdir); for (nfsdir = nfs->dircache, i = 0; nfsdir; nfsdir = nfsdir->next, i++) { if (i > MAX_DIR_CACHE) { LIBNFS_LIST_REMOVE(&nfs->dircache, nfsdir); nfs_free_nfsdir(nfsdir); break; } } } static struct nfsdir *nfs_dircache_find(struct nfs_context *nfs, struct nfs_fh3 *fh) { struct nfsdir *nfsdir; for (nfsdir = nfs->dircache; nfsdir; nfsdir = nfsdir->next) { if (nfsdir->fh.data.data_len == fh->data.data_len && !memcmp(nfsdir->fh.data.data_val, fh->data.data_val, fh->data.data_len)) { LIBNFS_LIST_REMOVE(&nfs->dircache, nfsdir); return nfsdir; } } return NULL; } struct nfs_cb_data; typedef int (*continue_func)(struct nfs_context *nfs, fattr3 *attr, struct nfs_cb_data *data); struct nfs_cb_data { struct nfs_context *nfs; struct nfsfh *nfsfh; char *saved_path, *path; int link_count, no_follow; nfs_cb cb; void *private_data; continue_func continue_cb; void *continue_data; void (*free_continue_data)(void *); uint64_t continue_int; struct nfs_fh3 fh; /* for multi-read/write calls. */ int error; int cancel; int oom; int num_calls; uint64_t offset, count, max_offset, org_offset, org_count; char *buffer; char *usrbuf; }; struct nfs_mcb_data { struct nfs_cb_data *data; uint64_t offset; uint64_t count; int update_pos; }; static int nfs_lookup_path_async_internal(struct nfs_context *nfs, fattr3 *attr, struct nfs_cb_data *data, struct nfs_fh3 *fh); static int nfs_normalize_path(struct nfs_context *nfs, char *path); void nfs_set_auth(struct nfs_context *nfs, struct AUTH *auth) { rpc_set_auth(nfs->rpc, auth); } int nfs_get_fd(struct nfs_context *nfs) { return rpc_get_fd(nfs->rpc); } int nfs_queue_length(struct nfs_context *nfs) { return rpc_queue_length(nfs->rpc); } int nfs_which_events(struct nfs_context *nfs) { return rpc_which_events(nfs->rpc); } int nfs_service(struct nfs_context *nfs, int revents) { return rpc_service(nfs->rpc, revents); } char *nfs_get_error(struct nfs_context *nfs) { return rpc_get_error(nfs->rpc); }; static int nfs_set_context_args(struct nfs_context *nfs, const char *arg, const char *val) { if (!strcmp(arg, "tcp-syncnt")) { rpc_set_tcp_syncnt(nfs_get_rpc_context(nfs), atoi(val)); } else if (!strcmp(arg, "uid")) { rpc_set_uid(nfs_get_rpc_context(nfs), atoi(val)); } else if (!strcmp(arg, "gid")) { rpc_set_gid(nfs_get_rpc_context(nfs), atoi(val)); } else if (!strcmp(arg, "readahead")) { rpc_set_readahead(nfs_get_rpc_context(nfs), atoi(val)); } else if (!strcmp(arg, "debug")) { rpc_set_debug(nfs_get_rpc_context(nfs), atoi(val)); } else if (!strcmp(arg, "auto-traverse-mounts")) { nfs->auto_traverse_mounts = atoi(val); } return 0; } static struct nfs_url *nfs_parse_url(struct nfs_context *nfs, const char *url, int dir, int incomplete) { struct nfs_url *urls; char *strp, *flagsp, *strp2; if (strncmp(url, "nfs://", 6)) { rpc_set_error(nfs->rpc, "Invalid URL specified"); return NULL; } urls = malloc(sizeof(struct nfs_url)); if (urls == NULL) { rpc_set_error(nfs->rpc, "Out of memory"); return NULL; } memset(urls, 0x00, sizeof(struct nfs_url)); urls->server = strdup(url + 6); if (urls->server == NULL) { nfs_destroy_url(urls); rpc_set_error(nfs->rpc, "Out of memory"); return NULL; } if (urls->server[0] == '/' || urls->server[0] == '\0' || urls->server[0] == '?') { if (incomplete) { flagsp = strchr(urls->server, '?'); goto flags; } nfs_destroy_url(urls); rpc_set_error(nfs->rpc, "Invalid server string"); return NULL; } strp = strchr(urls->server, '/'); if (strp == NULL) { if (incomplete) { flagsp = strchr(urls->server, '?'); goto flags; } nfs_destroy_url(urls); rpc_set_error(nfs->rpc, "Incomplete or invalid URL specified."); return NULL; } urls->path = strdup(strp); if (urls->path == NULL) { nfs_destroy_url(urls); rpc_set_error(nfs->rpc, "Out of memory"); return NULL; } *strp = 0; if (dir) { flagsp = strchr(urls->path, '?'); goto flags; } strp = strrchr(urls->path, '/'); if (strp == NULL) { if (incomplete) { flagsp = strchr(urls->path, '?'); goto flags; } nfs_destroy_url(urls); rpc_set_error(nfs->rpc, "Incomplete or invalid URL specified."); return NULL; } urls->file = strdup(strp); if (urls->path == NULL) { nfs_destroy_url(urls); rpc_set_error(nfs->rpc, "Out of memory"); return NULL; } *strp = 0; flagsp = strchr(urls->file, '?'); flags: if (flagsp) { *flagsp = 0; } if (urls->file && !strlen(urls->file)) { free(urls->file); urls->file = NULL; if (!incomplete) { nfs_destroy_url(urls); rpc_set_error(nfs->rpc, "Incomplete or invalid URL specified."); return NULL; } } while (flagsp != NULL && *(flagsp+1) != 0) { strp = flagsp + 1; flagsp = strchr(strp, '&'); if (flagsp) { *flagsp = 0; } strp2 = strchr(strp, '='); if (strp2) { *strp2 = 0; strp2++; nfs_set_context_args(nfs, strp, strp2); } } if (urls->server && strlen(urls->server) <= 1) { free(urls->server); urls->server = NULL; } return urls; } struct nfs_url *nfs_parse_url_full(struct nfs_context *nfs, const char *url) { return nfs_parse_url(nfs, url, 0, 0); } struct nfs_url *nfs_parse_url_dir(struct nfs_context *nfs, const char *url) { return nfs_parse_url(nfs, url, 1, 0); } struct nfs_url *nfs_parse_url_incomplete(struct nfs_context *nfs, const char *url) { return nfs_parse_url(nfs, url, 0, 1); } void nfs_destroy_url(struct nfs_url *url) { if (url) { free(url->server); free(url->path); free(url->file); } free(url); } struct nfs_context *nfs_init_context(void) { struct nfs_context *nfs; nfs = malloc(sizeof(struct nfs_context)); if (nfs == NULL) { return NULL; } memset(nfs, 0, sizeof(struct nfs_context)); nfs->rpc = rpc_init_context(); if (nfs->rpc == NULL) { free(nfs); return NULL; } nfs->cwd = strdup("/"); nfs->mask = 022; nfs->auto_traverse_mounts = 1; return nfs; } void nfs_destroy_context(struct nfs_context *nfs) { while (nfs->nested_mounts) { struct nested_mounts *mnt = nfs->nested_mounts; LIBNFS_LIST_REMOVE(&nfs->nested_mounts, mnt); free(mnt->path); free(mnt->fh.data.data_val); } rpc_destroy_context(nfs->rpc); nfs->rpc = NULL; if (nfs->server) { free(nfs->server); nfs->server = NULL; } if (nfs->export) { free(nfs->export); nfs->export = NULL; } if (nfs->cwd) { free(nfs->cwd); nfs->cwd = NULL; } if (nfs->rootfh.data.data_val != NULL) { free(nfs->rootfh.data.data_val); nfs->rootfh.data.data_val = NULL; } while (nfs->dircache) { struct nfsdir *nfsdir = nfs->dircache; LIBNFS_LIST_REMOVE(&nfs->dircache, nfsdir); nfs_free_nfsdir(nfsdir); } free(nfs); } struct rpc_cb_data { char *server; uint32_t program; uint32_t version; rpc_cb cb; void *private_data; }; void free_rpc_cb_data(struct rpc_cb_data *data) { free(data->server); data->server = NULL; free(data); } static void rpc_connect_program_5_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct rpc_cb_data *data = private_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); /* Dont want any more callbacks even if the socket is closed */ rpc->connect_cb = NULL; if (status == RPC_STATUS_ERROR) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(rpc, status, "Command was cancelled", data->private_data); free_rpc_cb_data(data); return; } data->cb(rpc, status, NULL, data->private_data); free_rpc_cb_data(data); } static void rpc_connect_program_4_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct rpc_cb_data *data = private_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); /* Dont want any more callbacks even if the socket is closed */ rpc->connect_cb = NULL; if (status == RPC_STATUS_ERROR) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(rpc, status, "Command was cancelled", data->private_data); free_rpc_cb_data(data); return; } switch (data->program) { case MOUNT_PROGRAM: if (rpc_mount3_null_async(rpc, rpc_connect_program_5_cb, data) != 0) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } return; case NFS_PROGRAM: if (rpc_nfs3_null_async(rpc, rpc_connect_program_5_cb, data) != 0) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } return; } data->cb(rpc, status, NULL, data->private_data); free_rpc_cb_data(data); } static void rpc_connect_program_3_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct rpc_cb_data *data = private_data; struct pmap3_string_result *gar; uint32_t rpc_port = 0; char *ptr; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(rpc, status, "Command was cancelled", data->private_data); free_rpc_cb_data(data); return; } switch (rpc->s.ss_family) { case AF_INET: rpc_port = *(uint32_t *)command_data; break; case AF_INET6: /* ouch. portmapper and ipv6 are not great */ gar = command_data; if (gar->addr == NULL) { break; } ptr = strrchr(gar->addr, '.'); if (ptr == NULL) { break; } rpc_port = atoi(ptr + 1); *ptr = 0; ptr = strrchr(gar->addr, '.'); if (ptr == NULL) { break; } rpc_port += 256 * atoi(ptr + 1); break; } if (rpc_port == 0) { rpc_set_error(rpc, "RPC error. Program is not available on %s", data->server); data->cb(rpc, RPC_STATUS_ERROR, rpc_get_error(rpc), data->private_data); free_rpc_cb_data(data); return; } rpc_disconnect(rpc, "normal disconnect"); if (rpc_connect_async(rpc, data->server, rpc_port, rpc_connect_program_4_cb, data) != 0) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } } static void rpc_connect_program_2_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct rpc_cb_data *data = private_data; struct pmap3_mapping map; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(rpc, status, "Command was cancelled", data->private_data); free_rpc_cb_data(data); return; } switch (rpc->s.ss_family) { case AF_INET: if (rpc_pmap2_getport_async(rpc, data->program, data->version, IPPROTO_TCP, rpc_connect_program_3_cb, private_data) != 0) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } break; case AF_INET6: map.prog=data->program; map.vers=data->version; map.netid=""; map.addr=""; map.owner=""; if (rpc_pmap3_getaddr_async(rpc, &map, rpc_connect_program_3_cb, private_data) != 0) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } break; } } static void rpc_connect_program_1_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct rpc_cb_data *data = private_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); /* Dont want any more callbacks even if the socket is closed */ rpc->connect_cb = NULL; if (status == RPC_STATUS_ERROR) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(rpc, status, "Command was cancelled", data->private_data); free_rpc_cb_data(data); return; } switch (rpc->s.ss_family) { case AF_INET: if (rpc_pmap2_null_async(rpc, rpc_connect_program_2_cb, data) != 0) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } break; case AF_INET6: if (rpc_pmap3_null_async(rpc, rpc_connect_program_2_cb, data) != 0) { data->cb(rpc, status, command_data, data->private_data); free_rpc_cb_data(data); return; } break; } } int rpc_connect_program_async(struct rpc_context *rpc, const char *server, int program, int version, rpc_cb cb, void *private_data) { struct rpc_cb_data *data; data = malloc(sizeof(struct rpc_cb_data)); if (data == NULL) { return -1; } memset(data, 0, sizeof(struct rpc_cb_data)); data->server = strdup(server); data->program = program; data->version = version; data->cb = cb; data->private_data = private_data; if (rpc_connect_async(rpc, server, 111, rpc_connect_program_1_cb, data) != 0) { rpc_set_error(rpc, "Failed to start connection"); free_rpc_cb_data(data); return -1; } return 0; } static void free_nfs_cb_data(struct nfs_cb_data *data) { if (data->continue_data != NULL) { assert(data->free_continue_data); data->free_continue_data(data->continue_data); } free(data->saved_path); free(data->fh.data.data_val); free(data->buffer); free(data); } static void free_nfsfh(struct nfsfh *nfsfh) { if (nfsfh->fh.data.data_val != NULL) { free(nfsfh->fh.data.data_val); nfsfh->fh.data.data_val = NULL; } free(nfsfh->ra.buf); free(nfsfh); } struct mount_attr_cb { int wait_count; struct nfs_cb_data *data; }; struct mount_attr_item_cb { struct mount_attr_cb *ma; struct nested_mounts *mnt; }; static void nfs_mount_12_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct mount_attr_item_cb *ma_item = private_data; struct mount_attr_cb *ma = ma_item->ma; struct nfs_cb_data *data = ma->data; struct nfs_context *nfs = data->nfs; GETATTR3res *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) goto finished; if (status == RPC_STATUS_CANCEL) goto finished; res = command_data; if (res->status != NFS3_OK) goto finished; ma_item->mnt->attr = res->GETATTR3res_u.resok.obj_attributes; finished: free(ma_item); ma->wait_count--; if (ma->wait_count > 0) return; free(ma); data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static void nfs_mount_11_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct mount_attr_cb *ma = NULL; struct nested_mounts *mnt; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } if (!nfs->nested_mounts) goto finished; /* nested mount traversals are best-effort only, so any * failures just means that we don't get traversal for that * particular mount. We do not fail the call from the application. */ ma = malloc(sizeof(struct mount_attr_cb)); if (ma == NULL) goto finished; memset(ma, 0, sizeof(struct mount_attr_cb)); ma->data = data; for(mnt = nfs->nested_mounts; mnt; mnt = mnt->next) { struct mount_attr_item_cb *ma_item; struct GETATTR3args args; ma_item = malloc(sizeof(struct mount_attr_item_cb)); if (ma_item == NULL) goto finished; ma_item->mnt = mnt; ma_item->ma = ma; memset(&args, 0, sizeof(GETATTR3args)); args.object = mnt->fh; if (rpc_nfs3_getattr_async(rpc, nfs_mount_12_cb, &args, ma_item) != 0) { free(ma_item); continue; } ma->wait_count++; } finished: if (ma && ma->wait_count) return; free(ma); data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static void nfs_mount_10_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; FSINFO3res *res = command_data; struct GETATTR3args args; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } nfs->readmax = res->FSINFO3res_u.resok.rtmax; nfs->writemax = res->FSINFO3res_u.resok.wtmax; if (nfs->readmax > NFS_MAX_XFER_SIZE) { rpc_set_error(rpc, "server max rsize of %lu is greater than libnfs supported %d bytes", nfs->readmax, NFS_MAX_XFER_SIZE); data->cb(-EINVAL, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (nfs->writemax > NFS_MAX_XFER_SIZE) { rpc_set_error(rpc, "server max wsize of %lu is greater than libnfs supported %d bytes", nfs->writemax, NFS_MAX_XFER_SIZE); data->cb(-EINVAL, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } memset(&args, 0, sizeof(GETATTR3args)); args.object = nfs->rootfh; if (rpc_nfs3_getattr_async(rpc, nfs_mount_11_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } } static void nfs_mount_9_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct FSINFO3args args; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } /* NFS TCP connections we want to autoreconnect after sessions are torn down (due to inactivity or error) */ rpc_set_autoreconnect(rpc); args.fsroot = nfs->rootfh; if (rpc_nfs3_fsinfo_async(rpc, nfs_mount_10_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } } struct mount_discovery_cb { int wait_count; struct nfs_cb_data *data; }; struct mount_discovery_item_cb { struct mount_discovery_cb *md_cb; char *path; }; static void nfs_mount_8_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct mount_discovery_item_cb *md_item_cb = private_data; struct mount_discovery_cb *md_cb = md_item_cb->md_cb; struct nfs_cb_data *data = md_cb->data; struct nfs_context *nfs = data->nfs; mountres3 *res; struct nested_mounts *mnt; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) goto finished; if (status == RPC_STATUS_CANCEL) goto finished; res = command_data; if (res->fhs_status != MNT3_OK) goto finished; mnt = malloc(sizeof(*mnt)); if (mnt == NULL) goto finished; memset(mnt, 0, sizeof(*mnt)); mnt->fh.data.data_len = res->mountres3_u.mountinfo.fhandle.fhandle3_len; mnt->fh.data.data_val = malloc(mnt->fh.data.data_len); if (mnt->fh.data.data_val == NULL) { free(mnt); goto finished; } memcpy(mnt->fh.data.data_val, res->mountres3_u.mountinfo.fhandle.fhandle3_val, mnt->fh.data.data_len); mnt->path = md_item_cb->path; md_item_cb->path = NULL; LIBNFS_LIST_ADD(&nfs->nested_mounts, mnt); finished: free(md_item_cb->path); free(md_item_cb); md_cb->wait_count--; if (md_cb->wait_count > 0) return; free(md_cb); rpc_disconnect(rpc, "normal disconnect"); if (rpc_connect_program_async(nfs->rpc, nfs->server, NFS_PROGRAM, NFS_V3, nfs_mount_9_cb, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } } static void nfs_mount_7_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; exports res; int len; struct mount_discovery_cb *md_cb = NULL; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } /* iterate over all exporst and check if we any exports nested * below out mount. */ len = strlen(nfs->export); if (!len) { data->cb(-EFAULT, nfs, "Export is empty", data->private_data); free_nfs_cb_data(data); return; } res = *(exports *)command_data; while (res) { struct mount_discovery_item_cb *md_item_cb; if (strncmp(nfs->export, res->ex_dir, len)) { res = res->ex_next; continue; } if (res->ex_dir[len - 1] != '/' && res->ex_dir[len] != '/') { res = res->ex_next; continue; } /* There is no need to fail the whole mount if anything * below fails. Just clean up and continue. At worst it * just mean that we might not be able to access any nested * mounts. */ md_item_cb = malloc(sizeof(*md_item_cb)); if (md_item_cb == NULL) continue; memset(md_item_cb, 0, sizeof(*md_item_cb)); md_item_cb->path = strdup(res->ex_dir + len - (nfs->export[len -1] == '/')); if (md_item_cb->path == NULL) { free(md_item_cb); continue; } if (md_cb == NULL) { md_cb = malloc(sizeof(*md_cb)); if (md_cb == NULL) { free(md_item_cb->path); free(md_item_cb); continue; } memset(md_cb, 0, sizeof(*md_cb)); md_cb->data = data; } md_item_cb->md_cb = md_cb; if (rpc_mount3_mnt_async(rpc, nfs_mount_8_cb, res->ex_dir, md_item_cb) != 0) { if (md_cb->wait_count == 0) { free(md_cb); md_cb = NULL; } free(md_item_cb->path); free(md_item_cb); continue; } md_cb->wait_count++; res = res->ex_next; } if (md_cb) return; /* We did not have any nested mounts to check so we can proceed straight * to reconnecting to NFSd. */ rpc_disconnect(rpc, "normal disconnect"); if (rpc_connect_program_async(nfs->rpc, nfs->server, NFS_PROGRAM, NFS_V3, nfs_mount_9_cb, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } } static void nfs_mount_6_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; mountres3 *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->fhs_status != MNT3_OK) { rpc_set_error(rpc, "RPC error: Mount failed with error %s(%d) %s(%d)", mountstat3_to_str(res->fhs_status), res->fhs_status, strerror(-mountstat3_to_errno(res->fhs_status)), -mountstat3_to_errno(res->fhs_status)); data->cb(mountstat3_to_errno(res->fhs_status), nfs, rpc_get_error(rpc), data->private_data); free_nfs_cb_data(data); return; } nfs->rootfh.data.data_len = res->mountres3_u.mountinfo.fhandle.fhandle3_len; nfs->rootfh.data.data_val = malloc(nfs->rootfh.data.data_len); if (nfs->rootfh.data.data_val == NULL) { rpc_set_error(rpc, "Out of memory. Could not allocate memory to store root filehandle"); data->cb(-ENOMEM, nfs, rpc_get_error(rpc), data->private_data); free_nfs_cb_data(data); return; } memcpy(nfs->rootfh.data.data_val, res->mountres3_u.mountinfo.fhandle.fhandle3_val, nfs->rootfh.data.data_len); if (nfs->auto_traverse_mounts) { if (rpc_mount3_export_async(rpc, nfs_mount_7_cb, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } return; } rpc_disconnect(rpc, "normal disconnect"); if (rpc_connect_program_async(nfs->rpc, nfs->server, NFS_PROGRAM, NFS_V3, nfs_mount_9_cb, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } } static void nfs_mount_5_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } if (rpc_mount3_mnt_async(rpc, nfs_mount_6_cb, nfs->export, data) != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } } /* * Async call for mounting an nfs share and geting the root filehandle */ int nfs_mount_async(struct nfs_context *nfs, const char *server, const char *export, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; char *new_server, *new_export; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for nfs mount data"); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); new_server = strdup(server); new_export = strdup(export); if (nfs->server != NULL) { free(nfs->server); } nfs->server = new_server; if (nfs->export != NULL) { free(nfs->export); } nfs->export = new_export; data->nfs = nfs; data->cb = cb; data->private_data = private_data; if (rpc_connect_program_async(nfs->rpc, server, MOUNT_PROGRAM, MOUNT_V3, nfs_mount_5_cb, data) != 0) { rpc_set_error(nfs->rpc, "Failed to start connection"); free_nfs_cb_data(data); return -1; } return 0; } /* * Functions to first look up a path, component by component, and then finally call a specific function once * the filehandle for the final component is found. */ static void nfs_lookup_path_2_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; READLINK3res *res; char *path, *newpath; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: READLINK of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } path = res->READLINK3res_u.resok.data; /* Handle absolute paths, ensuring that the path lies within the * export. */ if (path[0] == '/') { if (strstr(path, nfs->export) == path) { char *ptr = path + strlen(nfs->export); if (*ptr == '/') { newpath = strdup(ptr); } else if (*ptr == '\0') { newpath = strdup("/"); } else { data->cb(-ENOENT, nfs, "Symbolic link points outside export", data->private_data); free_nfs_cb_data(data); return; } } else { data->cb(-ENOENT, nfs, "Symbolic link points outside export", data->private_data); free_nfs_cb_data(data); return; } if (!newpath) goto nomem; } else { /* Handle relative paths, both the case where the current * component is an intermediate component and when it is the * final component. */ if (data->path[0]) { /* Since path points to a component and saved_path * always starts with '/', path[-1] is valid. */ data->path[-1] = '\0'; newpath = malloc(strlen(data->saved_path) + strlen(path) + strlen(data->path) + 6); if (!newpath) goto nomem; sprintf(newpath, "%s/../%s/%s", data->saved_path, path, data->path); } else { newpath = malloc(strlen(data->saved_path) + strlen(path) + 5); if (!newpath) goto nomem; sprintf(newpath, "%s/../%s", data->saved_path, path); } } free(data->saved_path); data->saved_path = newpath; if (nfs_normalize_path(nfs, data->saved_path) != 0) { data->cb(-ENOENT, nfs, "Symbolic link resolves to invalid path", data->private_data); free_nfs_cb_data(data); return; } data->path = data->saved_path; nfs_lookup_path_async_internal(nfs, NULL, data, &nfs->rootfh); return; nomem: data->cb(-ENOMEM, nfs, "Failed to allocate memory for path", data->private_data); free_nfs_cb_data(data); } static void nfs_lookup_path_1_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; LOOKUP3res *res; fattr3 *attr; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: Lookup of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } attr = res->LOOKUP3res_u.resok.obj_attributes.attributes_follow ? &res->LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes : NULL; /* This function will always invoke the callback and cleanup * for failures. So no need to check the return value. */ nfs_lookup_path_async_internal(nfs, attr, data, &res->LOOKUP3res_u.resok.object); } static int nfs_lookup_path_async_internal(struct nfs_context *nfs, fattr3 *attr, struct nfs_cb_data *data, struct nfs_fh3 *fh) { char *path, *slash; LOOKUP3args args; while (*data->path == '/') { data->path++; } path = data->path; slash = strchr(path, '/'); if (attr && attr->type == NF3LNK && (!data->no_follow || *path != '\0')) { READLINK3args rl_args; if (data->link_count++ >= MAX_LINK_COUNT) { data->cb(-ELOOP, nfs, "Too many levels of symbolic links", data->private_data); free_nfs_cb_data(data); return -1; } rl_args.symlink = *fh; if (rpc_nfs3_readlink_async(nfs->rpc, nfs_lookup_path_2_cb, &rl_args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READLINK call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } if (slash != NULL) { *slash = '/'; } return 0; } if (slash != NULL) { /* Clear slash so that path is a zero terminated string for * the current path component. Set it back to '/' again later * when we are finished referencing this component so that * data->saved_path will still point to the full * normalized path. */ *slash = 0; data->path = slash+1; } else { while (*data->path != 0) { data->path++; } } if (*path == 0) { data->fh.data.data_len = fh->data.data_len; data->fh.data.data_val = malloc(data->fh.data.data_len); if (data->fh.data.data_val == NULL) { rpc_set_error(nfs->rpc, "Out of memory: Failed to allocate fh for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } memcpy(data->fh.data.data_val, fh->data.data_val, data->fh.data.data_len); if (slash != NULL) { *slash = '/'; } data->continue_cb(nfs, attr, data); return 0; } memset(&args, 0, sizeof(LOOKUP3args)); args.what.dir = *fh; args.what.name = path; if (rpc_nfs3_lookup_async(nfs->rpc, nfs_lookup_path_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send lookup call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } if (slash != NULL) { *slash = '/'; } return 0; } static int nfs_normalize_path(struct nfs_context *nfs, char *path) { char *str; int len; /* // -> / */ while ((str = strstr(path, "//"))) { while(*str) { *str = *(str + 1); str++; } } /* /./ -> / */ while ((str = strstr(path, "/./"))) { while(*(str + 1)) { *str = *(str + 2); str++; } } /* ^/../ -> error */ if (!strncmp(path, "/../", 4)) { rpc_set_error(nfs->rpc, "Absolute path starts with '/../' " "during normalization"); return -1; } /* ^[^/] -> error */ if (path[0] != '/') { rpc_set_error(nfs->rpc, "Absolute path does not start with '/'"); return -1; } /* /string/../ -> / */ while ((str = strstr(path, "/../"))) { char *tmp; if (!strncmp(path, "/../", 4)) { rpc_set_error(nfs->rpc, "Absolute path starts with '/../' " "during normalization"); return -1; } tmp = str - 1; while (*tmp != '/') { tmp--; } str += 3; while((*(tmp++) = *(str++)) != '\0') ; } /* /$ -> \0 */ len = strlen(path); if (len > 1) { if (path[len - 1] == '/') { path[len - 1] = '\0'; len--; } } if (path[0] == '\0') { rpc_set_error(nfs->rpc, "Absolute path became '' " "during normalization"); return -1; } /* /.$ -> \0 */ if (len >= 2) { if (!strcmp(&path[len - 2], "/.")) { path[len - 2] = '\0'; len -= 2; } } /* ^/..$ -> error */ if (!strcmp(path, "/..")) { rpc_set_error(nfs->rpc, "Absolute path is '/..' " "during normalization"); return -1; } /* /string/..$ -> / */ if (len >= 3) { if (!strcmp(&path[len - 3], "/..")) { char *tmp = &path[len - 3]; while (*--tmp != '/') ; *tmp = '\0'; } } return 0; } static void nfs_lookup_path_getattr_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; GETATTR3res *res; fattr3 *attr; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: GETATTR of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } attr = &res->GETATTR3res_u.resok.obj_attributes; /* This function will always invoke the callback and cleanup * for failures. So no need to check the return value. */ nfs_lookup_path_async_internal(nfs, attr, data, &nfs->rootfh); } static int nfs_lookuppath_async(struct nfs_context *nfs, const char *path, int no_follow, nfs_cb cb, void *private_data, continue_func continue_cb, void *continue_data, void (*free_continue_data)(void *), uint64_t continue_int) { struct nfs_cb_data *data; struct GETATTR3args args; struct nfs_fh3 *fh; if (path[0] == '\0') { path = "."; } data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate " "nfs_cb_data structure"); if (free_continue_data) free_continue_data(continue_data); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->continue_cb = continue_cb; data->continue_data = continue_data; data->free_continue_data = free_continue_data; data->continue_int = continue_int; data->private_data = private_data; data->no_follow = no_follow; if (path[0] == '/') { data->saved_path = strdup(path); } else { data->saved_path = malloc(strlen(path) + strlen(nfs->cwd) + 2); if (data->saved_path == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to " "malloc path string"); free_nfs_cb_data(data); return -1; } sprintf(data->saved_path, "%s/%s", nfs->cwd, path); } if (data->saved_path == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to copy path string"); free_nfs_cb_data(data); return -1; } if (nfs_normalize_path(nfs, data->saved_path) != 0) { free_nfs_cb_data(data); return -1; } data->path = data->saved_path; fh = &nfs->rootfh; if (data->path[0]) { struct nested_mounts *mnt; /* Make sure we match on longest nested export. * TODO: If we make sure the list is sorted we can skip this * check and end the loop on first match. */ int max_match_len = 0; /* Do we need to switch to a different nested export ? */ for (mnt = nfs->nested_mounts; mnt; mnt = mnt->next) { if (strlen(mnt->path) < max_match_len) continue; if (strncmp(mnt->path, data->saved_path, strlen(mnt->path))) continue; if (data->saved_path[strlen(mnt->path)] != '\0' && data->saved_path[strlen(mnt->path)] != '/') continue; data->saved_path = strdup(data->path + strlen(mnt->path)); free(data->path); data->path = data->saved_path; fh = &mnt->fh; max_match_len = strlen(mnt->path); } /* This function will always invoke the callback and cleanup * for failures. So no need to check the return value. */ nfs_lookup_path_async_internal(nfs, NULL, data, fh); return 0; } /* We have a request for "", so just perform a GETATTR3 so we can * return the attributes to the caller. */ memset(&args, 0, sizeof(GETATTR3args)); args.object = *fh; if (rpc_nfs3_getattr_async(nfs->rpc, nfs_lookup_path_getattr_cb, &args, data) != 0) { free_nfs_cb_data(data); return -1; } return 0; } /* * Async stat() */ static dev_t specdata3_to_rdev(struct specdata3 *rdev) { #ifdef makedev return makedev(rdev->specdata1, rdev->specdata2); #else return 0; #endif } static void nfs_stat_1_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { GETATTR3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; #ifdef WIN32 struct __stat64 st; #else struct stat st; #endif assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: GETATTR of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } st.st_dev = res->GETATTR3res_u.resok.obj_attributes.fsid; st.st_ino = res->GETATTR3res_u.resok.obj_attributes.fileid; st.st_mode = res->GETATTR3res_u.resok.obj_attributes.mode; switch (res->GETATTR3res_u.resok.obj_attributes.type) { case NF3REG: st.st_mode |= S_IFREG; break; case NF3DIR: st.st_mode |= S_IFDIR; break; case NF3BLK: st.st_mode |= S_IFBLK; break; case NF3CHR: st.st_mode |= S_IFCHR; break; case NF3LNK: st.st_mode |= S_IFLNK; break; case NF3SOCK: st.st_mode |= S_IFSOCK; break; case NF3FIFO: st.st_mode |= S_IFIFO; break; } st.st_nlink = res->GETATTR3res_u.resok.obj_attributes.nlink; st.st_uid = res->GETATTR3res_u.resok.obj_attributes.uid; st.st_gid = res->GETATTR3res_u.resok.obj_attributes.gid; st.st_rdev = specdata3_to_rdev(&res->GETATTR3res_u.resok.obj_attributes.rdev); st.st_size = res->GETATTR3res_u.resok.obj_attributes.size; #ifndef WIN32 st.st_blksize = NFS_BLKSIZE; st.st_blocks = (res->GETATTR3res_u.resok.obj_attributes.used + 512 - 1) / 512; #endif//WIN32 st.st_atime = res->GETATTR3res_u.resok.obj_attributes.atime.seconds; st.st_mtime = res->GETATTR3res_u.resok.obj_attributes.mtime.seconds; st.st_ctime = res->GETATTR3res_u.resok.obj_attributes.ctime.seconds; #ifdef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC st.st_atim.tv_nsec = res->GETATTR3res_u.resok.obj_attributes.atime.nseconds; st.st_mtim.tv_nsec = res->GETATTR3res_u.resok.obj_attributes.mtime.nseconds; st.st_ctim.tv_nsec = res->GETATTR3res_u.resok.obj_attributes.ctime.nseconds; #endif data->cb(0, nfs, &st, data->private_data); free_nfs_cb_data(data); } static int nfs_stat_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { struct GETATTR3args args; memset(&args, 0, sizeof(GETATTR3args)); args.object = data->fh; if (rpc_nfs3_getattr_async(nfs->rpc, nfs_stat_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send STAT GETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_stat_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_stat_continue_internal, NULL, NULL, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async nfs_stat64() */ static void nfs_stat64_1_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { GETATTR3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfs_stat_64 st; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: GETATTR of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } st.nfs_dev = res->GETATTR3res_u.resok.obj_attributes.fsid; st.nfs_ino = res->GETATTR3res_u.resok.obj_attributes.fileid; st.nfs_mode = res->GETATTR3res_u.resok.obj_attributes.mode; switch (res->GETATTR3res_u.resok.obj_attributes.type) { case NF3REG: st.nfs_mode |= S_IFREG; break; case NF3DIR: st.nfs_mode |= S_IFDIR; break; case NF3BLK: st.nfs_mode |= S_IFBLK; break; case NF3CHR: st.nfs_mode |= S_IFCHR; break; case NF3LNK: st.nfs_mode |= S_IFLNK; break; case NF3SOCK: st.nfs_mode |= S_IFSOCK; break; case NF3FIFO: st.nfs_mode |= S_IFIFO; break; } st.nfs_nlink = res->GETATTR3res_u.resok.obj_attributes.nlink; st.nfs_uid = res->GETATTR3res_u.resok.obj_attributes.uid; st.nfs_gid = res->GETATTR3res_u.resok.obj_attributes.gid; st.nfs_rdev = specdata3_to_rdev(&res->GETATTR3res_u.resok.obj_attributes.rdev); st.nfs_size = res->GETATTR3res_u.resok.obj_attributes.size; st.nfs_blksize = NFS_BLKSIZE; st.nfs_blocks = (res->GETATTR3res_u.resok.obj_attributes.used + 512 - 1) / 512; st.nfs_atime = res->GETATTR3res_u.resok.obj_attributes.atime.seconds; st.nfs_mtime = res->GETATTR3res_u.resok.obj_attributes.mtime.seconds; st.nfs_ctime = res->GETATTR3res_u.resok.obj_attributes.ctime.seconds; st.nfs_atime_nsec = res->GETATTR3res_u.resok.obj_attributes.atime.nseconds; st.nfs_mtime_nsec = res->GETATTR3res_u.resok.obj_attributes.mtime.nseconds; st.nfs_ctime_nsec = res->GETATTR3res_u.resok.obj_attributes.ctime.nseconds; st.nfs_used = res->GETATTR3res_u.resok.obj_attributes.used; data->cb(0, nfs, &st, data->private_data); free_nfs_cb_data(data); } static int nfs_stat64_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { struct GETATTR3args args; memset(&args, 0, sizeof(GETATTR3args)); args.object = data->fh; if (rpc_nfs3_getattr_async(nfs->rpc, nfs_stat64_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send STAT GETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_stat64_async_internal(struct nfs_context *nfs, const char *path, int no_follow, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, no_follow, cb, private_data, nfs_stat64_continue_internal, NULL, NULL, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } int nfs_stat64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { return nfs_stat64_async_internal(nfs, path, 0, cb, private_data); } int nfs_lstat64_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { return nfs_stat64_async_internal(nfs, path, 1, cb, private_data); } /* * Async open() */ static void nfs_open_trunc_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfsfh *nfsfh; SETATTR3res *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: Setattr failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } nfsfh = malloc(sizeof(struct nfsfh)); if (nfsfh == NULL) { rpc_set_error(nfs->rpc, "NFS: Failed to allocate nfsfh structure"); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } memset(nfsfh, 0, sizeof(struct nfsfh)); if (data->continue_int & O_SYNC) { nfsfh->is_sync = 1; } if (data->continue_int & O_APPEND) { nfsfh->is_append = 1; } /* steal the filehandle */ nfsfh->fh = data->fh; data->fh.data.data_val = NULL; data->cb(0, nfs, nfsfh, data->private_data); free_nfs_cb_data(data); } static void nfs_open_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { ACCESS3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfsfh *nfsfh; unsigned int nfsmode = 0; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: ACCESS of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } if (data->continue_int & O_WRONLY) { nfsmode |= ACCESS3_MODIFY; } if (data->continue_int & O_RDWR) { nfsmode |= ACCESS3_READ|ACCESS3_MODIFY; } if (!(data->continue_int & (O_WRONLY|O_RDWR))) { nfsmode |= ACCESS3_READ; } if (res->ACCESS3res_u.resok.access != nfsmode) { rpc_set_error(nfs->rpc, "NFS: ACCESS denied. Required access %c%c%c. Allowed access %c%c%c", nfsmode&ACCESS3_READ?'r':'-', nfsmode&ACCESS3_MODIFY?'w':'-', nfsmode&ACCESS3_EXECUTE?'x':'-', res->ACCESS3res_u.resok.access&ACCESS3_READ?'r':'-', res->ACCESS3res_u.resok.access&ACCESS3_MODIFY?'w':'-', res->ACCESS3res_u.resok.access&ACCESS3_EXECUTE?'x':'-'); data->cb(-EACCES, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } /* Try to truncate it if we were requested to */ if ((data->continue_int & O_TRUNC) && (data->continue_int & (O_RDWR|O_WRONLY))) { SETATTR3args args; memset(&args, 0, sizeof(SETATTR3args)); args.object = data->fh; args.new_attributes.size.set_it = 1; args.new_attributes.size.set_size3_u.size = 0; if (rpc_nfs3_setattr_async(nfs->rpc, nfs_open_trunc_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send " "SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } return; } nfsfh = malloc(sizeof(struct nfsfh)); if (nfsfh == NULL) { rpc_set_error(nfs->rpc, "NFS: Failed to allocate nfsfh structure"); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } memset(nfsfh, 0, sizeof(struct nfsfh)); if (data->continue_int & O_SYNC) { nfsfh->is_sync = 1; } if (data->continue_int & O_APPEND) { nfsfh->is_append = 1; } /* steal the filehandle */ nfsfh->fh = data->fh; data->fh.data.data_val = NULL; data->cb(0, nfs, nfsfh, data->private_data); free_nfs_cb_data(data); } static int nfs_open_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { int nfsmode = 0; ACCESS3args args; if (data->continue_int & O_WRONLY) { nfsmode |= ACCESS3_MODIFY; } if (data->continue_int & O_RDWR) { nfsmode |= ACCESS3_READ|ACCESS3_MODIFY; } if (!(data->continue_int & (O_WRONLY|O_RDWR))) { nfsmode |= ACCESS3_READ; } memset(&args, 0, sizeof(ACCESS3args)); args.object = data->fh; args.access = nfsmode; if (rpc_nfs3_access_async(nfs->rpc, nfs_open_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send OPEN ACCESS " "call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_open_async(struct nfs_context *nfs, const char *path, int flags, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_open_continue_internal, NULL, NULL, flags) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async chdir() */ static int nfs_chdir_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { /* steal saved_path */ free(nfs->cwd); nfs->cwd = data->saved_path; data->saved_path = NULL; data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); return 0; } int nfs_chdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_chdir_continue_internal, NULL, NULL, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async pread() */ static void nfs_fill_READ3args(READ3args *args, struct nfsfh *fh, uint64_t offset, uint64_t count) { memset(args, 0, sizeof(READ3args)); args->file = fh->fh; args->offset = offset; args->count = count; } static void nfs_pread_mcb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_mcb_data *mdata = private_data; struct nfs_cb_data *data = mdata->data; struct nfs_context *nfs = data->nfs; READ3res *res; int cb_err; void *cb_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); data->num_calls--; if (status == RPC_STATUS_ERROR) { /* flag the failure but do not invoke callback until we have received all responses */ data->error = 1; } if (status == RPC_STATUS_CANCEL) { /* flag the cancellation but do not invoke callback until we have received all responses */ data->cancel = 1; } if (status == RPC_STATUS_SUCCESS) { res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: Read failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->error = 1; } else { uint64_t count = res->READ3res_u.resok.count; if (mdata->update_pos) data->nfsfh->offset += count; /* if we have more than one call or we have received a short read we need a reassembly buffer */ if (data->num_calls || (count < mdata->count && !res->READ3res_u.resok.eof)) { if (data->buffer == NULL) { data->buffer = malloc(data->count); if (data->buffer == NULL) { rpc_set_error(nfs->rpc, "Out-Of-Memory: Failed to allocate reassembly buffer for %d bytes", (int)data->count); data->oom = 1; } } } if (count > 0) { if (count <= mdata->count) { /* copy data into reassembly buffer if we have one */ if (data->buffer != NULL) { memcpy(&data->buffer[mdata->offset - data->offset], res->READ3res_u.resok.data.data_val, count); } if (data->max_offset < mdata->offset + count) { data->max_offset = mdata->offset + count; } } else { rpc_set_error(nfs->rpc, "NFS: Read overflow. Server has sent more data than requested!"); data->error = 1; } } /* check if we have received a short read */ if (count < mdata->count && !res->READ3res_u.resok.eof) { if (count == 0) { rpc_set_error(nfs->rpc, "NFS: Read failed. No bytes read and not at EOF!"); data->error = 1; } else { /* reissue reminder of this read request */ READ3args args; mdata->offset += count; mdata->count -= count; nfs_fill_READ3args(&args, data->nfsfh, mdata->offset, mdata->count); if (rpc_nfs3_read_async(nfs->rpc, nfs_pread_mcb, &args, mdata) == 0) { data->num_calls++; return; } else { rpc_set_error(nfs->rpc, "RPC error: Failed to send READ call for %s", data->path); data->oom = 1; } } } } } free(mdata); if (data->num_calls > 0) { /* still waiting for more replies */ return; } if (data->oom != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (data->error != 0) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (data->cancel != 0) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } if (data->buffer) { if (data->max_offset > data->org_offset + data->org_count) { data->max_offset = data->org_offset + data->org_count; } cb_err = data->max_offset - data->org_offset; cb_data = data->buffer + (data->org_offset - data->offset); } else { res = command_data; cb_err = res->READ3res_u.resok.count; cb_data = res->READ3res_u.resok.data.data_val; } data->nfsfh->ra.fh_offset = data->max_offset; if (data->nfsfh->ra.cur_ra) { free(data->nfsfh->ra.buf); data->nfsfh->ra.buf = data->buffer; data->nfsfh->ra.buf_offset = data->offset; data->nfsfh->ra.buf_count = data->count; data->nfsfh->ra.buf_ts = time(NULL); data->buffer = NULL; } data->cb(cb_err, nfs, cb_data, data->private_data); free_nfs_cb_data(data); } static void nfs_ra_invalidate(struct nfsfh *nfsfh) { free(nfsfh->ra.buf); nfsfh->ra.buf = NULL; nfsfh->ra.buf_offset = 0; nfsfh->ra.buf_count = 0; nfsfh->ra.buf_ts = time(NULL); nfsfh->ra.cur_ra = NFS_BLKSIZE; } static int nfs_pread_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, nfs_cb cb, void *private_data, int update_pos) { struct nfs_cb_data *data; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; data->nfsfh = nfsfh; data->org_offset = offset; data->org_count = count; assert(data->num_calls == 0); if (nfs->rpc->readahead && time(NULL) - nfsfh->ra.buf_ts > NFS_RA_TIMEOUT) { /* readahead cache timeout */ nfs_ra_invalidate(nfsfh); } if (nfs->rpc->readahead) { if (offset >= nfsfh->ra.last_offset && offset - NFS_BLKSIZE <= nfsfh->ra.fh_offset + nfsfh->ra.cur_ra) { if (nfs->rpc->readahead > nfsfh->ra.cur_ra) { nfsfh->ra.cur_ra <<= 1; } } else { nfsfh->ra.cur_ra = NFS_BLKSIZE; } nfsfh->ra.last_offset = offset; if (nfsfh->ra.buf_offset <= offset && nfsfh->ra.buf_offset + nfsfh->ra.buf_count >= offset + count) { /* serve request completely from cache */ data->buffer = malloc(count); if (data->buffer == NULL) { free_nfs_cb_data(data); return -ENOMEM; } memcpy(data->buffer, nfsfh->ra.buf + (offset - nfsfh->ra.buf_offset), count); data->cb(count, nfs, data->buffer, data->private_data); nfsfh->ra.fh_offset = offset + count; free_nfs_cb_data(data); return 0; } /* align start offset to blocksize */ count += offset & (NFS_BLKSIZE - 1); offset &= ~(NFS_BLKSIZE - 1); /* align end offset to blocksize and add readahead */ count += nfsfh->ra.cur_ra - 1; count &= ~(NFS_BLKSIZE - 1); data->buffer = malloc(count); if (data->buffer == NULL) { free_nfs_cb_data(data); return -ENOMEM; } data->offset = offset; data->count = count; if (nfsfh->ra.buf_count && nfsfh->ra.buf_offset <= offset && nfsfh->ra.buf_offset + nfsfh->ra.buf_count >= offset) { /* serve request partially from cache */ size_t overlap = (nfsfh->ra.buf_offset + nfsfh->ra.buf_count) - offset; if (overlap > count) count = overlap; memcpy(data->buffer, nfsfh->ra.buf + (offset - nfsfh->ra.buf_offset), overlap); offset += overlap; count -= overlap; } } else { data->offset = offset; data->count = count; } data->max_offset = offset; /* chop requests into chunks of at most READMAX bytes if necessary. * we send all reads in parallel so that performance is still good. */ do { uint64_t readcount = count; struct nfs_mcb_data *mdata; READ3args args; if (readcount > nfs_get_readmax(nfs)) { readcount = nfs_get_readmax(nfs); } mdata = malloc(sizeof(struct nfs_mcb_data)); if (mdata == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_mcb_data structure"); if (data->num_calls == 0) { free_nfs_cb_data(data); return -1; } data->oom = 1; break; } memset(mdata, 0, sizeof(struct nfs_mcb_data)); mdata->data = data; mdata->offset = offset; mdata->count = readcount; mdata->update_pos = update_pos; nfs_fill_READ3args(&args, nfsfh, offset, readcount); if (rpc_nfs3_read_async(nfs->rpc, nfs_pread_mcb, &args, mdata) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READ call for %s", data->path); free(mdata); if (data->num_calls == 0) { free_nfs_cb_data(data); return -1; } data->oom = 1; break; } count -= readcount; offset += readcount; data->num_calls++; } while (count > 0); return 0; } int nfs_pread_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, nfs_cb cb, void *private_data) { return nfs_pread_async_internal(nfs, nfsfh, offset, count, cb, private_data, 0); } /* * Async read() */ int nfs_read_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, nfs_cb cb, void *private_data) { return nfs_pread_async_internal(nfs, nfsfh, nfsfh->offset, count, cb, private_data, 1); } /* * Async pwrite() */ static void nfs_fill_WRITE3args (WRITE3args *args, struct nfsfh *fh, uint64_t offset, uint64_t count, void *buf) { memset(args, 0, sizeof(WRITE3args)); args->file = fh->fh; args->offset = offset; args->count = count; args->stable = fh->is_sync ? FILE_SYNC : UNSTABLE; args->data.data_len = count; args->data.data_val = buf; } static void nfs_pwrite_mcb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_mcb_data *mdata = private_data; struct nfs_cb_data *data = mdata->data; struct nfs_context *nfs = data->nfs; WRITE3res *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); data->num_calls--; if (status == RPC_STATUS_ERROR) { /* flag the failure but do not invoke callback until we have received all responses */ data->error = 1; } if (status == RPC_STATUS_CANCEL) { /* flag the cancellation but do not invoke callback until we have received all responses */ data->cancel = 1; } if (status == RPC_STATUS_SUCCESS) { res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: Write failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->error = 1; } else { uint64_t count = res->WRITE3res_u.resok.count; if (mdata->update_pos) data->nfsfh->offset += count; if (count < mdata->count) { if (count == 0) { rpc_set_error(nfs->rpc, "NFS: Write failed. No bytes written!"); data->error = 1; } else { /* reissue reminder of this write request */ WRITE3args args; mdata->offset += count; mdata->count -= count; nfs_fill_WRITE3args(&args, data->nfsfh, mdata->offset, mdata->count, &data->usrbuf[mdata->offset - data->offset]); if (rpc_nfs3_write_async(nfs->rpc, nfs_pwrite_mcb, &args, mdata) == 0) { data->num_calls++; return; } else { rpc_set_error(nfs->rpc, "RPC error: Failed to send WRITE call for %s", data->path); data->oom = 1; } } } if (count > 0) { if (data->max_offset < mdata->offset + count) { data->max_offset = mdata->offset + count; } } } } free(mdata); if (data->num_calls > 0) { /* still waiting for more replies */ return; } if (data->oom != 0) { data->cb(-ENOMEM, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (data->error != 0) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (data->cancel != 0) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } data->cb(data->max_offset - data->offset, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_pwrite_async_internal(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf, nfs_cb cb, void *private_data, int update_pos) { struct nfs_cb_data *data; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; data->nfsfh = nfsfh; data->usrbuf = buf; /* hello, clang-analyzer */ assert(data->num_calls == 0); /* chop requests into chunks of at most WRITEMAX bytes if necessary. * we send all writes in parallel so that performance is still good. */ data->max_offset = offset; data->offset = offset; do { uint64_t writecount = count; struct nfs_mcb_data *mdata; WRITE3args args; if (writecount > nfs_get_writemax(nfs)) { writecount = nfs_get_writemax(nfs); } mdata = malloc(sizeof(struct nfs_mcb_data)); if (mdata == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_mcb_data structure"); if (data->num_calls == 0) { free_nfs_cb_data(data); return -1; } data->oom = 1; break; } memset(mdata, 0, sizeof(struct nfs_mcb_data)); mdata->data = data; mdata->offset = offset; mdata->count = writecount; mdata->update_pos = update_pos; nfs_fill_WRITE3args(&args, nfsfh, offset, writecount, &buf[offset - data->offset]); if (rpc_nfs3_write_async(nfs->rpc, nfs_pwrite_mcb, &args, mdata) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send WRITE call for %s", data->path); free(mdata); if (data->num_calls == 0) { free_nfs_cb_data(data); return -1; } data->oom = 1; break; } count -= writecount; offset += writecount; data->num_calls++; } while (count > 0); return 0; } int nfs_pwrite_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t offset, uint64_t count, char *buf, nfs_cb cb, void *private_data) { return nfs_pwrite_async_internal(nfs, nfsfh, offset, count, buf, cb, private_data, 0); } /* * Async write() */ static void nfs_write_append_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; GETATTR3res *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: GETATTR failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } if (nfs_pwrite_async_internal(nfs, data->nfsfh, res->GETATTR3res_u.resok.obj_attributes.size, data->count, data->usrbuf, data->cb, data->private_data, 1) != 0) { data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } free_nfs_cb_data(data); } int nfs_write_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t count, char *buf, nfs_cb cb, void *private_data) { nfs_ra_invalidate(nfsfh); if (nfsfh->is_append) { struct GETATTR3args args; struct nfs_cb_data *data; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; data->nfsfh = nfsfh; data->usrbuf = buf; data->count = count; memset(&args, 0, sizeof(GETATTR3args)); args.object = nfsfh->fh; if (rpc_nfs3_getattr_async(nfs->rpc, nfs_write_append_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "out of memory: failed to send GETATTR"); free_nfs_cb_data(data); return -1; } return 0; } return nfs_pwrite_async_internal(nfs, nfsfh, nfsfh->offset, count, buf, cb, private_data, 1); } /* * close */ int nfs_close_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { free_nfsfh(nfsfh); cb(0, nfs, NULL, private_data); return 0; }; /* * Async fstat() */ int nfs_fstat_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; struct GETATTR3args args; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; memset(&args, 0, sizeof(GETATTR3args)); args.object = nfsfh->fh; if (rpc_nfs3_getattr_async(nfs->rpc, nfs_stat_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send STAT GETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } /* * Async fstat64() */ int nfs_fstat64_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; struct GETATTR3args args; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; memset(&args, 0, sizeof(GETATTR3args)); args.object = nfsfh->fh; if (rpc_nfs3_getattr_async(nfs->rpc, nfs_stat64_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send STAT GETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } /* * Async fsync() */ static void nfs_fsync_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; COMMIT3res *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: Commit failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } int nfs_fsync_async(struct nfs_context *nfs, struct nfsfh *nfsfh, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; struct COMMIT3args args; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; args.file = nfsfh->fh; args.offset = 0; args.count = 0; if (rpc_nfs3_commit_async(nfs->rpc, nfs_fsync_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send COMMIT call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } /* * Async ftruncate() */ static void nfs_ftruncate_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; SETATTR3res *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: Setattr failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } int nfs_ftruncate_async(struct nfs_context *nfs, struct nfsfh *nfsfh, uint64_t length, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; SETATTR3args args; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory: failed to allocate nfs_cb_data structure"); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; memset(&args, 0, sizeof(SETATTR3args)); args.object = nfsfh->fh; args.new_attributes.size.set_it = 1; args.new_attributes.size.set_size3_u.size = length; if (rpc_nfs3_setattr_async(nfs->rpc, nfs_ftruncate_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } /* * Async truncate() */ static int nfs_truncate_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { uint64_t offset = data->continue_int; struct nfsfh nfsfh; nfsfh.fh = data->fh; if (nfs_ftruncate_async(nfs, &nfsfh, offset, data->cb, data->private_data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } free_nfs_cb_data(data); return 0; } int nfs_truncate_async(struct nfs_context *nfs, const char *path, uint64_t length, nfs_cb cb, void *private_data) { uint64_t offset; offset = length; if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_truncate_continue_internal, NULL, NULL, offset) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async mkdir() */ static void nfs_mkdir_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { MKDIR3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; char *str = data->continue_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); str = &str[strlen(str) + 1]; if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: MKDIR of %s/%s failed with %s(%d)", data->saved_path, str, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_mkdir_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { char *str = data->continue_data; MKDIR3args args; str = &str[strlen(str) + 1]; memset(&args, 0, sizeof(MKDIR3args)); args.where.dir = data->fh; args.where.name = str; args.attributes.mode.set_it = 1; args.attributes.mode.set_mode3_u.mode = 0755; if (rpc_nfs3_mkdir_async(nfs->rpc, nfs_mkdir_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send MKDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_mkdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { char *new_path; char *ptr; new_path = strdup(path); if (new_path == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); return -1; } ptr = strrchr(new_path, '/'); if (ptr == NULL) { free(new_path); rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; } *ptr = 0; /* new_path now points to the parent directory, and beyond the nul terminateor is the new directory to create */ if (nfs_lookuppath_async(nfs, new_path, 0, cb, private_data, nfs_mkdir_continue_internal, new_path, free, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path component"); return -1; } return 0; } /* * Async rmdir() */ static void nfs_rmdir_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { RMDIR3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; char *str = data->continue_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); str = &str[strlen(str) + 1]; if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: RMDIR of %s/%s failed with %s(%d)", data->saved_path, str, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_rmdir_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { char *str = data->continue_data; RMDIR3args args; str = &str[strlen(str) + 1]; args.object.dir = data->fh; args.object.name = str; if (rpc_nfs3_rmdir_async(nfs->rpc, nfs_rmdir_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send RMDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_rmdir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { char *new_path; char *ptr; new_path = strdup(path); if (new_path == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); return -1; } ptr = strrchr(new_path, '/'); if (ptr == NULL) { free(new_path); rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; } *ptr = 0; /* new_path now points to the parent directory, and beyond the nul terminateor is the new directory to create */ if (nfs_lookuppath_async(nfs, new_path, 0, cb, private_data, nfs_rmdir_continue_internal, new_path, free, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async creat() */ struct create_cb_data { char *path; int flags; int mode; }; static void free_create_cb_data(void *ptr) { struct create_cb_data *data = ptr; free(data->path); free(data); } static void nfs_create_trunc_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfsfh *nfsfh = data->nfsfh; SETATTR3res *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); free_nfsfh(nfsfh); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); free_nfsfh(nfsfh); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: Setattr failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); free_nfsfh(nfsfh); return; } data->cb(0, nfs, nfsfh, data->private_data); free_nfs_cb_data(data); } static void nfs_create_2_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { LOOKUP3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfsfh *nfsfh; struct create_cb_data *cb_data = data->continue_data; char *str = cb_data->path; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } str = &str[strlen(str) + 1]; res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: CREATE of %s/%s failed with %s(%d)", data->saved_path, str, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); return; } nfsfh = malloc(sizeof(struct nfsfh)); if (nfsfh == NULL) { rpc_set_error(nfs->rpc, "NFS: Failed to allocate nfsfh structure"); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } memset(nfsfh, 0, sizeof(struct nfsfh)); if (cb_data->flags & O_SYNC) { nfsfh->is_sync = 1; } if (cb_data->flags & O_APPEND) { nfsfh->is_append = 1; } /* copy the filehandle */ nfsfh->fh.data.data_len = res->LOOKUP3res_u.resok.object.data.data_len; nfsfh->fh.data.data_val = malloc(nfsfh->fh.data.data_len); if (nfsfh->fh.data.data_val == NULL) { rpc_set_error(nfs->rpc, "Out of memory: Failed to allocate fh structure"); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); free(nfsfh); return; } memcpy(nfsfh->fh.data.data_val, res->LOOKUP3res_u.resok.object.data.data_val, nfsfh->fh.data.data_len); /* Try to truncate it if we were requested to */ if (cb_data->flags & O_TRUNC) { SETATTR3args args; data->nfsfh = nfsfh; memset(&args, 0, sizeof(SETATTR3args)); args.object = nfsfh->fh; args.new_attributes.size.set_it = 1; args.new_attributes.size.set_size3_u.size = 0; if (rpc_nfs3_setattr_async(nfs->rpc, nfs_create_trunc_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send " "SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); free_nfsfh(nfsfh); return; } return; } data->cb(0, nfs, nfsfh, data->private_data); free_nfs_cb_data(data); } static void nfs_create_1_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { CREATE3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct create_cb_data *cb_data = data->continue_data; char *str = cb_data->path; LOOKUP3args args; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } str = &str[strlen(str) + 1]; res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: CREATE of %s/%s failed with %s(%d)", data->saved_path, str, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } memset(&args, 0, sizeof(LOOKUP3args)); args.what.dir = data->fh; args.what.name = str; if (rpc_nfs3_lookup_async(nfs->rpc, nfs_create_2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send lookup call for %s/%s", data->saved_path, str); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } return; } static int nfs_create_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { struct create_cb_data *cb_data = data->continue_data; char *str = cb_data->path; CREATE3args args; str = &str[strlen(str) + 1]; memset(&args, 0, sizeof(CREATE3args)); args.where.dir = data->fh; args.where.name = str; args.how.mode = (cb_data->flags & O_EXCL) ? GUARDED : UNCHECKED; args.how.createhow3_u.obj_attributes.mode.set_it = 1; args.how.createhow3_u.obj_attributes.mode.set_mode3_u.mode = cb_data->mode; if (rpc_nfs3_create_async(nfs->rpc, nfs_create_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send CREATE call for %s/%s", data->path, str); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_create_async(struct nfs_context *nfs, const char *path, int flags, int mode, nfs_cb cb, void *private_data) { struct create_cb_data *cb_data; char *ptr; cb_data = malloc(sizeof(struct create_cb_data)); if (cb_data == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for cb data"); return -1; } cb_data->path = strdup(path); if (cb_data->path == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); free(cb_data); return -1; } ptr = strrchr(cb_data->path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); free_create_cb_data(cb_data); return -1; } *ptr = 0; cb_data->flags = flags; cb_data->mode = mode; /* new_path now points to the parent directory, and beyond the nul terminator is the new directory to create */ if (nfs_lookuppath_async(nfs, cb_data->path, 0, cb, private_data, nfs_create_continue_internal, cb_data, free_create_cb_data, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } int nfs_creat_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { return nfs_create_async(nfs, path, 0, mode, cb, private_data); } /* * Async unlink() */ static void nfs_unlink_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { REMOVE3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; char *str = data->continue_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); str = &str[strlen(str) + 1]; if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: REMOVE of %s/%s failed with %s(%d)", data->saved_path, str, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_unlink_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { char *str = data->continue_data; struct REMOVE3args args; str = &str[strlen(str) + 1]; args.object.dir = data->fh; args.object.name = str; if (rpc_nfs3_remove_async(nfs->rpc, nfs_unlink_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send REMOVE call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_unlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { char *new_path; char *ptr; new_path = strdup(path); if (new_path == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); return -1; } ptr = strrchr(new_path, '/'); if (ptr == NULL) { free(new_path); rpc_set_error(nfs->rpc, "Invalid path %s", path); return -1; } *ptr = 0; /* new_path now points to the parent directory, and beyond the nul terminateor is the new directory to create */ if (nfs_lookuppath_async(nfs, new_path, 0, cb, private_data, nfs_unlink_continue_internal, new_path, free, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async mknod() */ struct mknod_cb_data { char *path; int mode; int major; int minor; }; static void free_mknod_cb_data(void *ptr) { struct mknod_cb_data *data = ptr; free(data->path); free(data); } static void nfs_mknod_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { MKNOD3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; char *str = data->continue_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); str = &str[strlen(str) + 1]; if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: MKNOD of %s/%s failed with %s(%d)", data->saved_path, str, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_mknod_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { struct mknod_cb_data *cb_data = data->continue_data; char *str = cb_data->path; MKNOD3args args; str = &str[strlen(str) + 1]; args.where.dir = data->fh; args.where.name = str; switch (cb_data->mode & S_IFMT) { case S_IFCHR: args.what.type = NF3CHR; args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_it = 1; args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_mode3_u.mode = cb_data->mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); args.what.mknoddata3_u.chr_device.spec.specdata1 = cb_data->major; args.what.mknoddata3_u.chr_device.spec.specdata2 = cb_data->minor; break; case S_IFBLK: args.what.type = NF3BLK; args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_it = 1; args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_mode3_u.mode = cb_data->mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); args.what.mknoddata3_u.blk_device.spec.specdata1 = cb_data->major; args.what.mknoddata3_u.blk_device.spec.specdata2 = cb_data->minor; case S_IFSOCK: args.what.type = NF3SOCK; args.what.mknoddata3_u.sock_attributes.mode.set_it = 1; args.what.mknoddata3_u.sock_attributes.mode.set_mode3_u.mode = cb_data->mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); break; case S_IFIFO: args.what.type = NF3FIFO; args.what.mknoddata3_u.pipe_attributes.mode.set_it = 1; args.what.mknoddata3_u.pipe_attributes.mode.set_mode3_u.mode = cb_data->mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); break; default: rpc_set_error(nfs->rpc, "Invalid file type for NFS3/MKNOD call"); data->cb(-EINVAL, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } if (rpc_nfs3_mknod_async(nfs->rpc, nfs_mknod_cb, &args, data) != 0) { data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_mknod_async(struct nfs_context *nfs, const char *path, int mode, int dev, nfs_cb cb, void *private_data) { char *ptr; struct mknod_cb_data *cb_data; cb_data = malloc(sizeof(struct mknod_cb_data)); if (cb_data == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for cb data"); return -1; } cb_data->path = strdup(path); if (cb_data->path == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for path"); free(cb_data); return -1; } ptr = strrchr(cb_data->path, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", path); free_mknod_cb_data(cb_data); return -1; } *ptr = 0; cb_data->mode = mode; cb_data->major = major(dev); cb_data->minor = minor(dev); /* data->path now points to the parent directory, and beyond the nul terminateor is the new directory to create */ if (nfs_lookuppath_async(nfs, cb_data->path, 0, cb, private_data, nfs_mknod_continue_internal, cb_data, free_mknod_cb_data, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async opendir() */ /* ReadDirPlus Emulation Callback data */ struct rdpe_cb_data { int getattrcount; int status; struct nfs_cb_data *data; }; /* ReadDirPlus Emulation LOOKUP Callback data */ struct rdpe_lookup_cb_data { struct rdpe_cb_data *rdpe_cb_data; struct nfsdirent *nfsdirent; }; /* Workaround for servers lacking READDIRPLUS, use READDIR instead and a GETATTR-loop */ static void nfs_opendir3_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { LOOKUP3res *res = command_data; struct rdpe_lookup_cb_data *rdpe_lookup_cb_data = private_data; struct rdpe_cb_data *rdpe_cb_data = rdpe_lookup_cb_data->rdpe_cb_data; struct nfs_cb_data *data = rdpe_cb_data->data; struct nfsdir *nfsdir = data->continue_data; struct nfs_context *nfs = data->nfs; struct nfsdirent *nfsdirent = rdpe_lookup_cb_data->nfsdirent; assert(rpc->magic == RPC_CONTEXT_MAGIC); free(rdpe_lookup_cb_data); rdpe_cb_data->getattrcount--; if (status == RPC_STATUS_ERROR) { rpc_set_error(nfs->rpc, "LOOKUP during READDIRPLUS emulation " "failed with RPC_STATUS_ERROR"); rdpe_cb_data->status = RPC_STATUS_ERROR; } if (status == RPC_STATUS_CANCEL) { rpc_set_error(nfs->rpc, "LOOKUP during READDIRPLUS emulation " "failed with RPC_STATUS_CANCEL"); rdpe_cb_data->status = RPC_STATUS_CANCEL; } if (status == RPC_STATUS_SUCCESS && res->status == NFS3_OK) { if (res->LOOKUP3res_u.resok.obj_attributes.attributes_follow) { fattr3 *attributes = &res->LOOKUP3res_u.resok.obj_attributes.post_op_attr_u.attributes; nfsdirent->type = attributes->type; nfsdirent->mode = attributes->mode; switch (nfsdirent->type) { case NF3REG: nfsdirent->mode |= S_IFREG; break; case NF3DIR: nfsdirent->mode |= S_IFDIR; break; case NF3BLK: nfsdirent->mode |= S_IFBLK; break; case NF3CHR: nfsdirent->mode |= S_IFCHR; break; case NF3LNK: nfsdirent->mode |= S_IFLNK; break; case NF3SOCK: nfsdirent->mode |= S_IFSOCK; break; case NF3FIFO: nfsdirent->mode |= S_IFIFO; break; }; nfsdirent->size = attributes->size; nfsdirent->atime.tv_sec = attributes->atime.seconds; nfsdirent->atime.tv_usec = attributes->atime.nseconds/1000; nfsdirent->atime_nsec = attributes->atime.nseconds; nfsdirent->mtime.tv_sec = attributes->mtime.seconds; nfsdirent->mtime.tv_usec = attributes->mtime.nseconds/1000; nfsdirent->mtime_nsec = attributes->mtime.nseconds; nfsdirent->ctime.tv_sec = attributes->ctime.seconds; nfsdirent->ctime.tv_usec = attributes->ctime.nseconds/1000; nfsdirent->ctime_nsec = attributes->ctime.nseconds; nfsdirent->uid = attributes->uid; nfsdirent->gid = attributes->gid; nfsdirent->nlink = attributes->nlink; nfsdirent->dev = attributes->fsid; nfsdirent->rdev = specdata3_to_rdev(&attributes->rdev); nfsdirent->blksize = NFS_BLKSIZE; nfsdirent->blocks = (attributes->used + 512 - 1) / 512; nfsdirent->used = attributes->used; } } if (rdpe_cb_data->getattrcount == 0) { if (rdpe_cb_data->status != RPC_STATUS_SUCCESS) { rpc_set_error(nfs->rpc, "READDIRPLUS emulation " "failed: %s", rpc_get_error(rpc)); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); } else { data->cb(0, nfs, nfsdir, data->private_data); } free(rdpe_cb_data); data->continue_data = NULL; free_nfs_cb_data(data); } } static int lookup_missing_attributes(struct nfs_context *nfs, struct nfsdir *nfsdir, struct nfs_cb_data *data) { struct rdpe_cb_data *rdpe_cb_data; struct nfsdirent *nfsdirent; rdpe_cb_data = malloc(sizeof(struct rdpe_cb_data)); rdpe_cb_data->getattrcount = 0; rdpe_cb_data->status = RPC_STATUS_SUCCESS; rdpe_cb_data->data = data; for (nfsdirent = nfsdir->entries; nfsdirent; nfsdirent = nfsdirent->next) { struct rdpe_lookup_cb_data *rdpe_lookup_cb_data; LOOKUP3args args; /* If type == 0 we assume it is a case of the server not * giving us the attributes for this entry during READIR[PLUS] * so we fallback to LOOKUP3 */ if (nfsdirent->type != 0) { continue; } rdpe_lookup_cb_data = malloc(sizeof(struct rdpe_lookup_cb_data)); rdpe_lookup_cb_data->rdpe_cb_data = rdpe_cb_data; rdpe_lookup_cb_data->nfsdirent = nfsdirent; memset(&args, 0, sizeof(LOOKUP3args)); args.what.dir = data->fh; args.what.name = nfsdirent->name; if (rpc_nfs3_lookup_async(nfs->rpc, nfs_opendir3_cb, &args, rdpe_lookup_cb_data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send " "READDIR LOOKUP call"); /* if we have already commands in flight, we cant just * stop, we have to wait for the commands in flight to * complete */ continue; } rdpe_cb_data->getattrcount++; } return rdpe_cb_data->getattrcount; } static void nfs_opendir2_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { READDIR3res *res = command_data; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfsdir *nfsdir = data->continue_data; struct nfsdirent *nfsdirent; struct entry3 *entry; uint64_t cookie = 0; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: READDIR of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } entry =res->READDIR3res_u.resok.reply.entries; while (entry != NULL) { nfsdirent = malloc(sizeof(struct nfsdirent)); if (nfsdirent == NULL) { data->cb(-ENOMEM, nfs, "Failed to allocate dirent", data->private_data); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } memset(nfsdirent, 0, sizeof(struct nfsdirent)); nfsdirent->name = strdup(entry->name); if (nfsdirent->name == NULL) { data->cb(-ENOMEM, nfs, "Failed to allocate dirent->name", data->private_data); free(nfsdirent); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } nfsdirent->inode = entry->fileid; nfsdirent->next = nfsdir->entries; nfsdir->entries = nfsdirent; cookie = entry->cookie; entry = entry->nextentry; } if (res->READDIR3res_u.resok.reply.eof == 0) { READDIR3args args; args.dir = data->fh; args.cookie = cookie; memcpy(&args.cookieverf, res->READDIR3res_u.resok.cookieverf, sizeof(cookieverf3)); args.count = 8192; if (rpc_nfs3_readdir_async(nfs->rpc, nfs_opendir2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } return; } if (res->READDIR3res_u.resok.dir_attributes.attributes_follow) nfsdir->attr = res->READDIR3res_u.resok.dir_attributes.post_op_attr_u.attributes; /* steal the dirhandle */ nfsdir->current = nfsdir->entries; if (lookup_missing_attributes(nfs, nfsdir, data) == 0) { data->cb(0, nfs, nfsdir, data->private_data); data->continue_data = NULL; free_nfs_cb_data(data); return; } } static void nfs_opendir_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { READDIRPLUS3res *res = command_data; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfsdir *nfsdir = data->continue_data; struct entryplus3 *entry; uint64_t cookie = 0; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR || (status == RPC_STATUS_SUCCESS && res->status == NFS3ERR_NOTSUPP)){ READDIR3args args; args.dir = data->fh; args.cookie = cookie; memset(&args.cookieverf, 0, sizeof(cookieverf3)); args.count = 8192; if (rpc_nfs3_readdir_async(nfs->rpc, nfs_opendir2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: READDIRPLUS of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } entry =res->READDIRPLUS3res_u.resok.reply.entries; while (entry != NULL) { struct nfsdirent *nfsdirent; fattr3 *attr = NULL; nfsdirent = malloc(sizeof(struct nfsdirent)); if (nfsdirent == NULL) { data->cb(-ENOMEM, nfs, "Failed to allocate dirent", data->private_data); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } memset(nfsdirent, 0, sizeof(struct nfsdirent)); nfsdirent->name = strdup(entry->name); if (nfsdirent->name == NULL) { data->cb(-ENOMEM, nfs, "Failed to allocate dirent->name", data->private_data); free(nfsdirent); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } nfsdirent->inode = entry->fileid; if (entry->name_attributes.attributes_follow) attr = &entry->name_attributes.post_op_attr_u.attributes; if (attr == NULL) { struct nested_mounts *mnt; int splen = strlen(data->saved_path); /* A single '/' is a special case, treat it as * zero-length below. */ if (splen == 1) splen = 0; /* No name attributes. Is it a nested mount then?*/ for(mnt = nfs->nested_mounts; mnt; mnt = mnt->next) { if (strncmp(data->saved_path, mnt->path, splen)) continue; if (mnt->path[splen] != '/') continue; if (strcmp(mnt->path + splen + 1, entry->name)) continue; attr = &mnt->attr; break; } } if (attr) { nfsdirent->type = attr->type; nfsdirent->mode = attr->mode; switch (nfsdirent->type) { case NF3REG: nfsdirent->mode |= S_IFREG; break; case NF3DIR: nfsdirent->mode |= S_IFDIR; break; case NF3BLK: nfsdirent->mode |= S_IFBLK; break; case NF3CHR: nfsdirent->mode |= S_IFCHR; break; case NF3LNK: nfsdirent->mode |= S_IFLNK; break; case NF3SOCK: nfsdirent->mode |= S_IFSOCK; break; case NF3FIFO: nfsdirent->mode |= S_IFIFO; break; }; nfsdirent->size = attr->size; nfsdirent->atime.tv_sec = attr->atime.seconds; nfsdirent->atime.tv_usec = attr->atime.nseconds/1000; nfsdirent->atime_nsec = attr->atime.nseconds; nfsdirent->mtime.tv_sec = attr->mtime.seconds; nfsdirent->mtime.tv_usec = attr->mtime.nseconds/1000; nfsdirent->mtime_nsec = attr->mtime.nseconds; nfsdirent->ctime.tv_sec = attr->ctime.seconds; nfsdirent->ctime.tv_usec = attr->ctime.nseconds/1000; nfsdirent->ctime_nsec = attr->ctime.nseconds; nfsdirent->uid = attr->uid; nfsdirent->gid = attr->gid; nfsdirent->nlink = attr->nlink; nfsdirent->dev = attr->fsid; nfsdirent->rdev = specdata3_to_rdev(&attr->rdev); nfsdirent->blksize = NFS_BLKSIZE; nfsdirent->blocks = (attr->used + 512 - 1) / 512; nfsdirent->used = attr->used; } nfsdirent->next = nfsdir->entries; nfsdir->entries = nfsdirent; cookie = entry->cookie; entry = entry->nextentry; } if (res->READDIRPLUS3res_u.resok.reply.eof == 0) { READDIRPLUS3args args; args.dir = data->fh; args.cookie = cookie; memcpy(&args.cookieverf, res->READDIRPLUS3res_u.resok.cookieverf, sizeof(cookieverf3)); args.dircount = 8192; args.maxcount = 8192; if (rpc_nfs3_readdirplus_async(nfs->rpc, nfs_opendir_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIRPLUS call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); nfs_free_nfsdir(nfsdir); data->continue_data = NULL; free_nfs_cb_data(data); return; } return; } if (res->READDIRPLUS3res_u.resok.dir_attributes.attributes_follow) nfsdir->attr = res->READDIRPLUS3res_u.resok.dir_attributes.post_op_attr_u.attributes; /* steal the dirhandle */ nfsdir->current = nfsdir->entries; if (lookup_missing_attributes(nfs, nfsdir, data) == 0) { data->cb(0, nfs, nfsdir, data->private_data); /* We can not free data->continue_data here */ data->continue_data = NULL; free_nfs_cb_data(data); return; } } static int nfs_opendir_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { READDIRPLUS3args args; struct nfsdir *nfsdir = data->continue_data;; struct nfsdir *cached; cached = nfs_dircache_find(nfs, &data->fh); if (cached) { if (attr && attr->mtime.seconds == cached->attr.mtime.seconds) { cached->current = cached->entries; data->cb(0, nfs, cached, data->private_data); free_nfs_cb_data(data); return 0; } else { /* cache must be stale */ nfs_free_nfsdir(cached); } } nfsdir->fh.data.data_len = data->fh.data.data_len; nfsdir->fh.data.data_val = malloc(nfsdir->fh.data.data_len); if (nfsdir->fh.data.data_val == NULL) { rpc_set_error(nfs->rpc, "OOM when allocating fh for nfsdir"); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } memcpy(nfsdir->fh.data.data_val, data->fh.data.data_val, data->fh.data.data_len); args.dir = data->fh; args.cookie = 0; memset(&args.cookieverf, 0, sizeof(cookieverf3)); args.dircount = 8192; args.maxcount = 8192; if (rpc_nfs3_readdirplus_async(nfs->rpc, nfs_opendir_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READDIRPLUS call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_opendir_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { struct nfsdir *nfsdir; nfsdir = malloc(sizeof(struct nfsdir)); if (nfsdir == NULL) { rpc_set_error(nfs->rpc, "failed to allocate buffer for nfsdir"); return -1; } memset(nfsdir, 0, sizeof(struct nfsdir)); if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_opendir_continue_internal, nfsdir, free, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } struct nfsdirent *nfs_readdir(struct nfs_context *nfs _U_, struct nfsdir *nfsdir) { struct nfsdirent *nfsdirent = nfsdir->current; if (nfsdir->current != NULL) { nfsdir->current = nfsdir->current->next; } return nfsdirent; } /* * closedir() */ void nfs_closedir(struct nfs_context *nfs, struct nfsdir *nfsdir) { nfs_dircache_add(nfs, nfsdir); } /* * getcwd() */ void nfs_getcwd(struct nfs_context *nfs, const char **cwd) { if (cwd) { *cwd = nfs->cwd; } } /* * Async lseek() */ struct lseek_cb_data { struct nfs_context *nfs; struct nfsfh *nfsfh; int64_t offset; nfs_cb cb; void *private_data; }; static void nfs_lseek_1_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { GETATTR3res *res; struct lseek_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; uint64_t size = 0; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: GETATTR failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free(data); return; } size = res->GETATTR3res_u.resok.obj_attributes.size; if (data->offset < 0 && (uint64_t)(-data->offset) > size) { data->cb(-EINVAL, nfs, &data->nfsfh->offset, data->private_data); } else { data->nfsfh->offset = data->offset + size; data->cb(0, nfs, &data->nfsfh->offset, data->private_data); } free(data); } int nfs_lseek_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int64_t offset, int whence, nfs_cb cb, void *private_data) { struct lseek_cb_data *data; struct GETATTR3args args; if (whence == SEEK_SET) { if (offset < 0) { cb(-EINVAL, nfs, &nfsfh->offset, private_data); } else { nfsfh->offset = offset; cb(0, nfs, &nfsfh->offset, private_data); } return 0; } if (whence == SEEK_CUR) { if (offset < 0 && nfsfh->offset < (uint64_t)(-offset)) { cb(-EINVAL, nfs, &nfsfh->offset, private_data); } else { nfsfh->offset += offset; cb(0, nfs, &nfsfh->offset, private_data); } return 0; } data = malloc(sizeof(struct lseek_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "Out Of Memory: Failed to malloc lseek cb data"); return -1; } data->nfs = nfs; data->nfsfh = nfsfh; data->offset = offset; data->cb = cb; data->private_data = private_data; memset(&args, 0, sizeof(GETATTR3args)); args.object = nfsfh->fh; if (rpc_nfs3_getattr_async(nfs->rpc, nfs_lseek_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send LSEEK GETATTR call"); free(data); return -1; } return 0; } /* * Async statvfs() */ static void nfs_statvfs_1_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { FSSTAT3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct statvfs svfs; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: FSSTAT of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } svfs.f_bsize = NFS_BLKSIZE; svfs.f_frsize = NFS_BLKSIZE; svfs.f_blocks = res->FSSTAT3res_u.resok.tbytes/NFS_BLKSIZE; svfs.f_bfree = res->FSSTAT3res_u.resok.fbytes/NFS_BLKSIZE; svfs.f_bavail = res->FSSTAT3res_u.resok.abytes/NFS_BLKSIZE; svfs.f_files = res->FSSTAT3res_u.resok.tfiles; svfs.f_ffree = res->FSSTAT3res_u.resok.ffiles; #if !defined(ANDROID) svfs.f_favail = res->FSSTAT3res_u.resok.afiles; svfs.f_fsid = 0; svfs.f_flag = 0; svfs.f_namemax = 256; #endif data->cb(0, nfs, &svfs, data->private_data); free_nfs_cb_data(data); } static int nfs_statvfs_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { FSSTAT3args args; args.fsroot = data->fh; if (rpc_nfs3_fsstat_async(nfs->rpc, nfs_statvfs_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send FSSTAT call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_statvfs_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_statvfs_continue_internal, NULL, NULL, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async readlink() */ static void nfs_readlink_1_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { READLINK3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: READLINK of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, res->READLINK3res_u.resok.data, data->private_data); free_nfs_cb_data(data); } static int nfs_readlink_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { READLINK3args args; args.symlink = data->fh; if (rpc_nfs3_readlink_async(nfs->rpc, nfs_readlink_1_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send READLINK call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_readlink_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, 1, cb, private_data, nfs_readlink_continue_internal, NULL, NULL, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async chmod() */ static void nfs_chmod_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; SETATTR3res *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: SETATTR failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_chmod_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { SETATTR3args args; memset(&args, 0, sizeof(SETATTR3args)); args.object = data->fh; args.new_attributes.mode.set_it = 1; args.new_attributes.mode.set_mode3_u.mode = data->continue_int; if (rpc_nfs3_setattr_async(nfs->rpc, nfs_chmod_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_chmod_async_internal(struct nfs_context *nfs, const char *path, int no_follow, int mode, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, no_follow, cb, private_data, nfs_chmod_continue_internal, NULL, NULL, mode) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } int nfs_chmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { return nfs_chmod_async_internal(nfs, path, 0, mode, cb, private_data); } int nfs_lchmod_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { return nfs_chmod_async_internal(nfs, path, 1, mode, cb, private_data); } /* * Async fchmod() */ int nfs_fchmod_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int mode, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for nfs mount data"); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; data->continue_int = mode; data->fh.data.data_len = nfsfh->fh.data.data_len; data->fh.data.data_val = malloc(data->fh.data.data_len); if (data->fh.data.data_val == NULL) { rpc_set_error(nfs->rpc, "Out of memory: Failed to allocate fh"); free_nfs_cb_data(data); return -1; } memcpy(data->fh.data.data_val, nfsfh->fh.data.data_val, data->fh.data.data_len); if (nfs_chmod_continue_internal(nfs, NULL, data) != 0) { return -1; } return 0; } /* * Async chown() */ static void nfs_chown_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; SETATTR3res *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: SETATTR failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } struct nfs_chown_data { uid_t uid; gid_t gid; }; static int nfs_chown_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { SETATTR3args args; struct nfs_chown_data *chown_data = data->continue_data; memset(&args, 0, sizeof(SETATTR3args)); args.object = data->fh; if (chown_data->uid != (uid_t)-1) { args.new_attributes.uid.set_it = 1; args.new_attributes.uid.set_uid3_u.uid = chown_data->uid; } if (chown_data->gid != (gid_t)-1) { args.new_attributes.gid.set_it = 1; args.new_attributes.gid.set_gid3_u.gid = chown_data->gid; } if (rpc_nfs3_setattr_async(nfs->rpc, nfs_chown_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_chown_async_internal(struct nfs_context *nfs, const char *path, int no_follow, int uid, int gid, nfs_cb cb, void *private_data) { struct nfs_chown_data *chown_data; chown_data = malloc(sizeof(struct nfs_chown_data)); if (chown_data == NULL) { rpc_set_error(nfs->rpc, "Failed to allocate memory for chown data structure"); return -1; } chown_data->uid = uid; chown_data->gid = gid; if (nfs_lookuppath_async(nfs, path, no_follow, cb, private_data, nfs_chown_continue_internal, chown_data, free, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } int nfs_chown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data) { return nfs_chown_async_internal(nfs, path, 0, uid, gid, cb, private_data); } int nfs_lchown_async(struct nfs_context *nfs, const char *path, int uid, int gid, nfs_cb cb, void *private_data) { return nfs_chown_async_internal(nfs, path, 1, uid, gid, cb, private_data); } /* * Async fchown() */ int nfs_fchown_async(struct nfs_context *nfs, struct nfsfh *nfsfh, int uid, int gid, nfs_cb cb, void *private_data) { struct nfs_cb_data *data; struct nfs_chown_data *chown_data; chown_data = malloc(sizeof(struct nfs_chown_data)); if (chown_data == NULL) { rpc_set_error(nfs->rpc, "Failed to allocate memory for chown data structure"); return -1; } chown_data->uid = uid; chown_data->gid = gid; data = malloc(sizeof(struct nfs_cb_data)); if (data == NULL) { rpc_set_error(nfs->rpc, "out of memory. failed to allocate memory for fchown data"); free(chown_data); return -1; } memset(data, 0, sizeof(struct nfs_cb_data)); data->nfs = nfs; data->cb = cb; data->private_data = private_data; data->continue_data = chown_data; data->free_continue_data = free; data->fh.data.data_len = nfsfh->fh.data.data_len; data->fh.data.data_val = malloc(data->fh.data.data_len); if (data->fh.data.data_val == NULL) { rpc_set_error(nfs->rpc, "Out of memory: Failed to allocate fh"); free_nfs_cb_data(data); return -1; } memcpy(data->fh.data.data_val, nfsfh->fh.data.data_val, data->fh.data.data_len); if (nfs_chown_continue_internal(nfs, NULL, data) != 0) { return -1; } return 0; } /* * Async utimes() */ static void nfs_utimes_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; SETATTR3res *res; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: SETATTR failed with %s(%d)", nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_utimes_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { SETATTR3args args; struct timeval *utimes_data = data->continue_data; memset(&args, 0, sizeof(SETATTR3args)); args.object = data->fh; if (utimes_data != NULL) { args.new_attributes.atime.set_it = SET_TO_CLIENT_TIME; args.new_attributes.atime.set_atime_u.atime.seconds = utimes_data[0].tv_sec; args.new_attributes.atime.set_atime_u.atime.nseconds = utimes_data[0].tv_usec * 1000; args.new_attributes.mtime.set_it = SET_TO_CLIENT_TIME; args.new_attributes.mtime.set_mtime_u.mtime.seconds = utimes_data[1].tv_sec; args.new_attributes.mtime.set_mtime_u.mtime.nseconds = utimes_data[1].tv_usec * 1000; } else { args.new_attributes.atime.set_it = SET_TO_SERVER_TIME; args.new_attributes.mtime.set_it = SET_TO_SERVER_TIME; } if (rpc_nfs3_setattr_async(nfs->rpc, nfs_utimes_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SETATTR call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_utimes_async_internal(struct nfs_context *nfs, const char *path, int no_follow, struct timeval *times, nfs_cb cb, void *private_data) { struct timeval *new_times = NULL; if (times != NULL) { new_times = malloc(sizeof(struct timeval)*2); if (new_times == NULL) { rpc_set_error(nfs->rpc, "Failed to allocate memory for timeval structure"); return -1; } memcpy(new_times, times, sizeof(struct timeval)*2); } if (nfs_lookuppath_async(nfs, path, no_follow, cb, private_data, nfs_utimes_continue_internal, new_times, free, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } int nfs_utimes_async(struct nfs_context *nfs, const char *path, struct timeval *times, nfs_cb cb, void *private_data) { return nfs_utimes_async_internal(nfs, path, 0, times, cb, private_data); } int nfs_lutimes_async(struct nfs_context *nfs, const char *path, struct timeval *times, nfs_cb cb, void *private_data) { return nfs_utimes_async_internal(nfs, path, 1, times, cb, private_data); } /* * Async utime() */ int nfs_utime_async(struct nfs_context *nfs, const char *path, struct utimbuf *times, nfs_cb cb, void *private_data) { struct timeval *new_times = NULL; if (times != NULL) { new_times = malloc(sizeof(struct timeval)*2); if (new_times == NULL) { rpc_set_error(nfs->rpc, "Failed to allocate memory for timeval structure"); return -1; } new_times[0].tv_sec = times->actime; new_times[0].tv_usec = 0; new_times[1].tv_sec = times->modtime; new_times[1].tv_usec = 0; } if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_utimes_continue_internal, new_times, free, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async access() */ static void nfs_access_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { ACCESS3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; unsigned int mode = 0; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: ACCESS of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } if ((data->continue_int & R_OK) && (res->ACCESS3res_u.resok.access & ACCESS3_READ)) { mode |= R_OK; } if ((data->continue_int & W_OK) && (res->ACCESS3res_u.resok.access & (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE))) { mode |= W_OK; } if ((data->continue_int & X_OK) && (res->ACCESS3res_u.resok.access & (ACCESS3_LOOKUP | ACCESS3_EXECUTE))) { mode |= X_OK; } if (data->continue_int != mode) { rpc_set_error(nfs->rpc, "NFS: ACCESS denied. Required access %c%c%c. Allowed access %c%c%c", data->continue_int&R_OK?'r':'-', data->continue_int&W_OK?'w':'-', data->continue_int&X_OK?'x':'-', mode&R_OK?'r':'-', mode&W_OK?'w':'-', mode&X_OK?'x':'-'); data->cb(-EACCES, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_access_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { int nfsmode = 0; ACCESS3args args; if (data->continue_int & R_OK) { nfsmode |= ACCESS3_READ; } if (data->continue_int & W_OK) { nfsmode |= ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE; } if (data->continue_int & X_OK) { nfsmode |= ACCESS3_LOOKUP | ACCESS3_EXECUTE; } memset(&args, 0, sizeof(ACCESS3args)); args.object = data->fh; args.access = nfsmode; if (rpc_nfs3_access_async(nfs->rpc, nfs_access_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send OPEN ACCESS call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_access_async(struct nfs_context *nfs, const char *path, int mode, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_access_continue_internal, NULL, NULL, mode & (R_OK | W_OK | X_OK)) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async access2() */ static void nfs_access2_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { ACCESS3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; unsigned int result = 0; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: ACCESS of %s failed with %s(%d)", data->saved_path, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } if (res->ACCESS3res_u.resok.access & ACCESS3_READ) { result |= R_OK; } if (res->ACCESS3res_u.resok.access & (ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE)) { result |= W_OK; } if (res->ACCESS3res_u.resok.access & (ACCESS3_LOOKUP | ACCESS3_EXECUTE)) { result |= X_OK; } data->cb(result, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_access2_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { ACCESS3args args; memset(&args, 0, sizeof(ACCESS3args)); args.object = data->fh; args.access = ACCESS3_READ | ACCESS3_LOOKUP | ACCESS3_MODIFY | ACCESS3_EXTEND | ACCESS3_DELETE | ACCESS3_EXECUTE; if (rpc_nfs3_access_async(nfs->rpc, nfs_access2_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send OPEN ACCESS call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_access2_async(struct nfs_context *nfs, const char *path, nfs_cb cb, void *private_data) { if (nfs_lookuppath_async(nfs, path, 0, cb, private_data, nfs_access2_continue_internal, NULL, NULL, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async symlink() */ struct nfs_symlink_data { char *oldpath; char *newpathparent; char *newpathobject; }; static void free_nfs_symlink_data(void *mem) { struct nfs_symlink_data *data = mem; if (data->oldpath != NULL) { free(data->oldpath); } if (data->newpathparent != NULL) { free(data->newpathparent); } if (data->newpathobject != NULL) { free(data->newpathobject); } free(data); } static void nfs_symlink_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { SYMLINK3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfs_symlink_data *symlink_data = data->continue_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: SYMLINK %s/%s -> %s failed with %s(%d)", symlink_data->newpathparent, symlink_data->newpathobject, symlink_data->oldpath, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_symlink_continue_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { struct nfs_symlink_data *symlink_data = data->continue_data; SYMLINK3args args; memset(&args, 0, sizeof(SYMLINK3args)); args.where.dir = data->fh; args.where.name = symlink_data->newpathobject; args.symlink.symlink_attributes.mode.set_it = 1; args.symlink.symlink_attributes.mode.set_mode3_u.mode = S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH; args.symlink.symlink_data = symlink_data->oldpath; if (rpc_nfs3_symlink_async(nfs->rpc, nfs_symlink_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send SYMLINK call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } int nfs_symlink_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data) { char *ptr; struct nfs_symlink_data *symlink_data; symlink_data = malloc(sizeof(struct nfs_symlink_data)); if (symlink_data == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for symlink data"); return -1; } memset(symlink_data, 0, sizeof(struct nfs_symlink_data)); symlink_data->oldpath = strdup(oldpath); if (symlink_data->oldpath == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for oldpath"); free_nfs_symlink_data(symlink_data); return -1; } symlink_data->newpathparent = strdup(newpath); if (symlink_data->newpathparent == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for new path"); free_nfs_symlink_data(symlink_data); return -1; } ptr = strrchr(symlink_data->newpathparent, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", oldpath); free_nfs_symlink_data(symlink_data); return -1; } *ptr = 0; ptr++; symlink_data->newpathobject = strdup(ptr); if (symlink_data->newpathobject == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate mode buffer for new path"); free_nfs_symlink_data(symlink_data); return -1; } if (nfs_lookuppath_async(nfs, symlink_data->newpathparent, 0, cb, private_data, nfs_symlink_continue_internal, symlink_data, free_nfs_symlink_data, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async rename() */ struct nfs_rename_data { char *oldpath; char *oldobject; struct nfs_fh3 olddir; char *newpath; char *newobject; struct nfs_fh3 newdir; }; static void free_nfs_rename_data(void *mem) { struct nfs_rename_data *data = mem; if (data->oldpath != NULL) { free(data->oldpath); } if (data->olddir.data.data_val != NULL) { free(data->olddir.data.data_val); } if (data->newpath != NULL) { free(data->newpath); } if (data->newdir.data.data_val != NULL) { free(data->newdir.data.data_val); } free(data); } static void nfs_rename_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { RENAME3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfs_rename_data *rename_data = data->continue_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: RENAME %s/%s -> %s/%s failed with %s(%d)", rename_data->oldpath, rename_data->oldobject, rename_data->newpath, rename_data->newobject, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_rename_continue_2_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { struct nfs_rename_data *rename_data = data->continue_data; RENAME3args args; /* steal the filehandle */ rename_data->newdir = data->fh; data->fh.data.data_val = NULL; args.from.dir = rename_data->olddir; args.from.name = rename_data->oldobject; args.to.dir = rename_data->newdir; args.to.name = rename_data->newobject; if (rpc_nfs3_rename_async(nfs->rpc, nfs_rename_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send RENAME call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } static int nfs_rename_continue_1_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { struct nfs_rename_data *rename_data = data->continue_data; char* newpath = strdup(rename_data->newpath); if (!newpath) { rpc_set_error(nfs->rpc, "Out of memory. Could not allocate memory to store target path for rename"); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } /* steal the filehandle */ rename_data->olddir = data->fh; data->fh.data.data_val = NULL; if (nfs_lookuppath_async(nfs, rename_data->newpath, 0, data->cb, data->private_data, nfs_rename_continue_2_internal, rename_data, free_nfs_rename_data, 0) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send LOOKUP call for %s", newpath); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); free(newpath); return -1; } data->continue_data = NULL; free_nfs_cb_data(data); free(newpath); return 0; } int nfs_rename_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data) { char *ptr; struct nfs_rename_data *rename_data; rename_data = malloc(sizeof(struct nfs_rename_data)); if (rename_data == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for rename data"); return -1; } memset(rename_data, 0, sizeof(struct nfs_rename_data)); rename_data->oldpath = strdup(oldpath); if (rename_data->oldpath == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for oldpath"); free_nfs_rename_data(rename_data); return -1; } ptr = strrchr(rename_data->oldpath, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", oldpath); free_nfs_rename_data(rename_data); return -1; } *ptr = 0; ptr++; rename_data->oldobject = ptr; rename_data->newpath = strdup(newpath); if (rename_data->newpath == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for newpath"); free_nfs_rename_data(rename_data); return -1; } ptr = strrchr(rename_data->newpath, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", newpath); free_nfs_rename_data(rename_data); return -1; } *ptr = 0; ptr++; rename_data->newobject = ptr; if (nfs_lookuppath_async(nfs, rename_data->oldpath, 0, cb, private_data, nfs_rename_continue_1_internal, rename_data, free_nfs_rename_data, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Async link() */ struct nfs_link_data { char *oldpath; struct nfs_fh3 oldfh; char *newpath; char *newobject; struct nfs_fh3 newdir; }; static void free_nfs_link_data(void *mem) { struct nfs_link_data *data = mem; if (data->oldpath != NULL) { free(data->oldpath); } if (data->oldfh.data.data_val != NULL) { free(data->oldfh.data.data_val); } if (data->newpath != NULL) { free(data->newpath); } if (data->newdir.data.data_val != NULL) { free(data->newdir.data.data_val); } free(data); } static void nfs_link_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { LINK3res *res; struct nfs_cb_data *data = private_data; struct nfs_context *nfs = data->nfs; struct nfs_link_data *link_data = data->continue_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(-EFAULT, nfs, command_data, data->private_data); free_nfs_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(-EINTR, nfs, "Command was cancelled", data->private_data); free_nfs_cb_data(data); return; } res = command_data; if (res->status != NFS3_OK) { rpc_set_error(nfs->rpc, "NFS: LINK %s -> %s/%s failed with %s(%d)", link_data->oldpath, link_data->newpath, link_data->newobject, nfsstat3_to_str(res->status), nfsstat3_to_errno(res->status)); data->cb(nfsstat3_to_errno(res->status), nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return; } data->cb(0, nfs, NULL, data->private_data); free_nfs_cb_data(data); } static int nfs_link_continue_2_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { struct nfs_link_data *link_data = data->continue_data; LINK3args args; /* steal the filehandle */ link_data->newdir = data->fh; data->fh.data.data_val = NULL; memset(&args, 0, sizeof(LINK3args)); args.file = link_data->oldfh; args.link.dir = link_data->newdir; args.link.name = link_data->newobject; if (rpc_nfs3_link_async(nfs->rpc, nfs_link_cb, &args, data) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send LINK call for %s", data->path); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } return 0; } static int nfs_link_continue_1_internal(struct nfs_context *nfs, fattr3 *attr _U_, struct nfs_cb_data *data) { struct nfs_link_data *link_data = data->continue_data; /* steal the filehandle */ link_data->oldfh = data->fh; data->fh.data.data_val = NULL; if (nfs_lookuppath_async(nfs, link_data->newpath, 0, data->cb, data->private_data, nfs_link_continue_2_internal, link_data, free_nfs_link_data, 0) != 0) { rpc_set_error(nfs->rpc, "RPC error: Failed to send LOOKUP call for %s", link_data->newpath); data->cb(-ENOMEM, nfs, rpc_get_error(nfs->rpc), data->private_data); free_nfs_cb_data(data); return -1; } data->continue_data = NULL; free_nfs_cb_data(data); return 0; } int nfs_link_async(struct nfs_context *nfs, const char *oldpath, const char *newpath, nfs_cb cb, void *private_data) { char *ptr; struct nfs_link_data *link_data; link_data = malloc(sizeof(struct nfs_link_data)); if (link_data == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for link data"); return -1; } memset(link_data, 0, sizeof(struct nfs_link_data)); link_data->oldpath = strdup(oldpath); if (link_data->oldpath == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for oldpath"); free_nfs_link_data(link_data); return -1; } link_data->newpath = strdup(newpath); if (link_data->newpath == NULL) { rpc_set_error(nfs->rpc, "Out of memory, failed to allocate buffer for newpath"); free_nfs_link_data(link_data); return -1; } ptr = strrchr(link_data->newpath, '/'); if (ptr == NULL) { rpc_set_error(nfs->rpc, "Invalid path %s", newpath); free_nfs_link_data(link_data); return -1; } *ptr = 0; ptr++; link_data->newobject = ptr; if (nfs_lookuppath_async(nfs, link_data->oldpath, 0, cb, private_data, nfs_link_continue_1_internal, link_data, free_nfs_link_data, 0) != 0) { rpc_set_error(nfs->rpc, "Out of memory: failed to start parsing the path components"); return -1; } return 0; } /* * Get the maximum supported READ3 size by the server */ uint64_t nfs_get_readmax(struct nfs_context *nfs) { return nfs->readmax; } /* * Get the maximum supported WRITE3 size by the server */ uint64_t nfs_get_writemax(struct nfs_context *nfs) { return nfs->writemax; } void nfs_set_tcp_syncnt(struct nfs_context *nfs, int v) { rpc_set_tcp_syncnt(nfs->rpc, v); } void nfs_set_uid(struct nfs_context *nfs, int uid) { rpc_set_uid(nfs->rpc, uid); } void nfs_set_gid(struct nfs_context *nfs, int gid) { rpc_set_gid(nfs->rpc, gid); } void nfs_set_readahead(struct nfs_context *nfs, uint32_t v) { rpc_set_readahead(nfs->rpc, v); } void nfs_set_debug(struct nfs_context *nfs, int level) { rpc_set_debug(nfs->rpc, level); } void nfs_set_error(struct nfs_context *nfs, char *error_string, ...) { va_list ap; char *str = NULL; va_start(ap, error_string); str = malloc(1024); vsnprintf(str, 1024, error_string, ap); if (nfs->rpc->error_string != NULL) { free(nfs->rpc->error_string); } nfs->rpc->error_string = str; va_end(ap); } struct mount_cb_data { rpc_cb cb; void *private_data; char *server; }; static void free_mount_cb_data(struct mount_cb_data *data) { if (data->server != NULL) { free(data->server); data->server = NULL; } free(data); } static void mount_export_5_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct mount_cb_data *data = private_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status == RPC_STATUS_ERROR) { data->cb(rpc, -EFAULT, command_data, data->private_data); free_mount_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(rpc, -EINTR, "Command was cancelled", data->private_data); free_mount_cb_data(data); return; } data->cb(rpc, 0, command_data, data->private_data); if (rpc_disconnect(rpc, "normal disconnect") != 0) { rpc_set_error(rpc, "Failed to disconnect\n"); } free_mount_cb_data(data); } static void mount_export_4_cb(struct rpc_context *rpc, int status, void *command_data, void *private_data) { struct mount_cb_data *data = private_data; assert(rpc->magic == RPC_CONTEXT_MAGIC); /* Dont want any more callbacks even if the socket is closed */ rpc->connect_cb = NULL; if (status == RPC_STATUS_ERROR) { data->cb(rpc, -EFAULT, command_data, data->private_data); free_mount_cb_data(data); return; } if (status == RPC_STATUS_CANCEL) { data->cb(rpc, -EINTR, "Command was cancelled", data->private_data); free_mount_cb_data(data); return; } if (rpc_mount3_export_async(rpc, mount_export_5_cb, data) != 0) { data->cb(rpc, -ENOMEM, command_data, data->private_data); free_mount_cb_data(data); return; } } int mount_getexports_async(struct rpc_context *rpc, const char *server, rpc_cb cb, void *private_data) { struct mount_cb_data *data; assert(rpc->magic == RPC_CONTEXT_MAGIC); data = malloc(sizeof(struct mount_cb_data)); if (data == NULL) { return -1; } memset(data, 0, sizeof(struct mount_cb_data)); data->cb = cb; data->private_data = private_data; data->server = strdup(server); if (data->server == NULL) { free_mount_cb_data(data); return -1; } if (rpc_connect_program_async(rpc, data->server, MOUNT_PROGRAM, MOUNT_V3, mount_export_4_cb, data) != 0) { rpc_set_error(rpc, "Failed to start connection"); free_mount_cb_data(data); return -1; } return 0; } struct rpc_context *nfs_get_rpc_context(struct nfs_context *nfs) { assert(nfs->rpc->magic == RPC_CONTEXT_MAGIC); return nfs->rpc; } const char *nfs_get_server(struct nfs_context *nfs) { return nfs->server; } const char *nfs_get_export(struct nfs_context *nfs) { return nfs->export; } const struct nfs_fh3 *nfs_get_rootfh(struct nfs_context *nfs) { return &nfs->rootfh; } struct nfs_fh3 *nfs_get_fh(struct nfsfh *nfsfh) { return &nfsfh->fh; } uint16_t nfs_umask(struct nfs_context *nfs, uint16_t mask) { uint16_t tmp = nfs->mask; nfs->mask = mask; return tmp; } libnfs-libnfs-1.9.8/lib/pdu.c000066400000000000000000000233151255745034100157750ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_STRINGS_H #include #endif #include #include #include #include #include #include "slist.h" #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" void rpc_reset_queue(struct rpc_queue *q) { q->head = NULL; q->tail = NULL; } /* * Push to the tail end of the queue */ void rpc_enqueue(struct rpc_queue *q, struct rpc_pdu *pdu) { if (q->head == NULL) q->head = pdu; else q->tail->next = pdu; q->tail = pdu; pdu->next = NULL; } /* * Push to the front/head of the queue */ void rpc_return_to_queue(struct rpc_queue *q, struct rpc_pdu *pdu) { pdu->next = q->head; q->head = pdu; if (q->tail == NULL) q->tail = pdu; } unsigned int rpc_hash_xid(uint32_t xid) { return (xid * 7919) % HASHES; } struct rpc_pdu *rpc_allocate_pdu(struct rpc_context *rpc, int program, int version, int procedure, rpc_cb cb, void *private_data, zdrproc_t zdr_decode_fn, int zdr_decode_bufsize) { struct rpc_pdu *pdu; struct rpc_msg msg; assert(rpc->magic == RPC_CONTEXT_MAGIC); pdu = malloc(sizeof(struct rpc_pdu)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory: Failed to allocate pdu structure"); return NULL; } memset(pdu, 0, sizeof(struct rpc_pdu)); pdu->xid = rpc->xid++; pdu->cb = cb; pdu->private_data = private_data; pdu->zdr_decode_fn = zdr_decode_fn; pdu->zdr_decode_bufsize = zdr_decode_bufsize; zdrmem_create(&pdu->zdr, rpc->encodebuf, rpc->encodebuflen, ZDR_ENCODE); if (rpc->is_udp == 0) { zdr_setpos(&pdu->zdr, 4); /* skip past the record marker */ } memset(&msg, 0, sizeof(struct rpc_msg)); msg.xid = pdu->xid; msg.direction = CALL; msg.body.cbody.rpcvers = RPC_MSG_VERSION; msg.body.cbody.prog = program; msg.body.cbody.vers = version; msg.body.cbody.proc = procedure; msg.body.cbody.cred = rpc->auth->ah_cred; msg.body.cbody.verf = rpc->auth->ah_verf; if (zdr_callmsg(rpc, &pdu->zdr, &msg) == 0) { rpc_set_error(rpc, "zdr_callmsg failed with %s", rpc_get_error(rpc)); zdr_destroy(&pdu->zdr); free(pdu); return NULL; } return pdu; } void rpc_free_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu) { assert(rpc->magic == RPC_CONTEXT_MAGIC); if (pdu->outdata.data != NULL) { free(pdu->outdata.data); pdu->outdata.data = NULL; } if (pdu->zdr_decode_buf != NULL) { zdr_free(pdu->zdr_decode_fn, pdu->zdr_decode_buf); free(pdu->zdr_decode_buf); pdu->zdr_decode_buf = NULL; } zdr_destroy(&pdu->zdr); free(pdu); } void rpc_set_next_xid(struct rpc_context *rpc, uint32_t xid) { rpc->xid = xid; } int rpc_queue_pdu(struct rpc_context *rpc, struct rpc_pdu *pdu) { int size, recordmarker; assert(rpc->magic == RPC_CONTEXT_MAGIC); size = zdr_getpos(&pdu->zdr); /* for udp we dont queue, we just send it straight away */ if (rpc->is_udp != 0) { unsigned int hash; // XXX add a rpc->udp_dest_sock_size and get rid of sys/socket.h and netinet/in.h if (sendto(rpc->fd, rpc->encodebuf, size, MSG_DONTWAIT, rpc->udp_dest, sizeof(struct sockaddr_in)) < 0) { rpc_set_error(rpc, "Sendto failed with errno %s", strerror(errno)); rpc_free_pdu(rpc, pdu); return -1; } hash = rpc_hash_xid(pdu->xid); rpc_enqueue(&rpc->waitpdu[hash], pdu); return 0; } /* write recordmarker */ zdr_setpos(&pdu->zdr, 0); recordmarker = (size - 4) | 0x80000000; zdr_int(&pdu->zdr, &recordmarker); pdu->outdata.size = size; pdu->outdata.data = malloc(pdu->outdata.size); if (pdu->outdata.data == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate buffer for pdu\n"); rpc_free_pdu(rpc, pdu); return -1; } memcpy(pdu->outdata.data, rpc->encodebuf, pdu->outdata.size); rpc_enqueue(&rpc->outqueue, pdu); return 0; } int rpc_get_pdu_size(char *buf) { uint32_t size; size = ntohl(*(uint32_t *)buf); return (size & 0x7fffffff) + 4; } static int rpc_process_reply(struct rpc_context *rpc, struct rpc_pdu *pdu, ZDR *zdr) { struct rpc_msg msg; assert(rpc->magic == RPC_CONTEXT_MAGIC); memset(&msg, 0, sizeof(struct rpc_msg)); msg.body.rbody.reply.areply.verf = _null_auth; if (pdu->zdr_decode_bufsize > 0) { if (pdu->zdr_decode_buf != NULL) { free(pdu->zdr_decode_buf); } pdu->zdr_decode_buf = malloc(pdu->zdr_decode_bufsize); if (pdu->zdr_decode_buf == NULL) { rpc_set_error(rpc, "Failed to allocate memory for " "zdr_encode_buf in rpc_process_reply"); pdu->cb(rpc, RPC_STATUS_ERROR, "Failed to allocate " "buffer for decoding of ZDR reply", pdu->private_data); return 0; } memset(pdu->zdr_decode_buf, 0, pdu->zdr_decode_bufsize); } msg.body.rbody.reply.areply.reply_data.results.where = pdu->zdr_decode_buf; msg.body.rbody.reply.areply.reply_data.results.proc = pdu->zdr_decode_fn; if (zdr_replymsg(rpc, zdr, &msg) == 0) { rpc_set_error(rpc, "zdr_replymsg failed in rpc_process_reply: " "%s", rpc_get_error(rpc)); pdu->cb(rpc, RPC_STATUS_ERROR, "Message rejected by server", pdu->private_data); if (pdu->zdr_decode_buf != NULL) { free(pdu->zdr_decode_buf); pdu->zdr_decode_buf = NULL; } return 0; } if (msg.body.rbody.stat != MSG_ACCEPTED) { pdu->cb(rpc, RPC_STATUS_ERROR, "RPC Packet not accepted by the server", pdu->private_data); return 0; } switch (msg.body.rbody.reply.areply.stat) { case SUCCESS: pdu->cb(rpc, RPC_STATUS_SUCCESS, pdu->zdr_decode_buf, pdu->private_data); break; case PROG_UNAVAIL: pdu->cb(rpc, RPC_STATUS_ERROR, "Server responded: Program not available", pdu->private_data); break; case PROG_MISMATCH: pdu->cb(rpc, RPC_STATUS_ERROR, "Server responded: Program version mismatch", pdu->private_data); break; case PROC_UNAVAIL: pdu->cb(rpc, RPC_STATUS_ERROR, "Server responded: Procedure not available", pdu->private_data); break; case GARBAGE_ARGS: pdu->cb(rpc, RPC_STATUS_ERROR, "Server responded: Garbage arguments", pdu->private_data); break; case SYSTEM_ERR: pdu->cb(rpc, RPC_STATUS_ERROR, "Server responded: System Error", pdu->private_data); break; default: pdu->cb(rpc, RPC_STATUS_ERROR, "Unknown rpc response from server", pdu->private_data); break; } return 0; } int rpc_process_pdu(struct rpc_context *rpc, char *buf, int size) { struct rpc_pdu *pdu, *prev_pdu; struct rpc_queue *q; ZDR zdr; int pos, recordmarker = 0; unsigned int hash; uint32_t xid; char *reasbuf = NULL; assert(rpc->magic == RPC_CONTEXT_MAGIC); memset(&zdr, 0, sizeof(ZDR)); zdrmem_create(&zdr, buf, size, ZDR_DECODE); if (rpc->is_udp == 0) { if (zdr_int(&zdr, &recordmarker) == 0) { rpc_set_error(rpc, "zdr_int reading recordmarker failed"); zdr_destroy(&zdr); return -1; } if (!(recordmarker&0x80000000)) { zdr_destroy(&zdr); if (rpc_add_fragment(rpc, buf+4, size-4) != 0) { rpc_set_error(rpc, "Failed to queue fragment for reassembly."); return -1; } return 0; } } /* reassembly */ if (recordmarker != 0 && rpc->fragments != NULL) { struct rpc_fragment *fragment; uint32_t total = size - 4; char *ptr; zdr_destroy(&zdr); for (fragment = rpc->fragments; fragment; fragment = fragment->next) { total += fragment->size; } reasbuf = malloc(total); if (reasbuf == NULL) { rpc_set_error(rpc, "Failed to reassemble PDU"); rpc_free_all_fragments(rpc); return -1; } ptr = reasbuf; for (fragment = rpc->fragments; fragment; fragment = fragment->next) { memcpy(ptr, fragment->data, fragment->size); ptr += fragment->size; } memcpy(ptr, buf + 4, size - 4); zdrmem_create(&zdr, reasbuf, total, ZDR_DECODE); rpc_free_all_fragments(rpc); } pos = zdr_getpos(&zdr); if (zdr_int(&zdr, (int *)&xid) == 0) { rpc_set_error(rpc, "zdr_int reading xid failed"); zdr_destroy(&zdr); if (reasbuf != NULL) { free(reasbuf); } return -1; } zdr_setpos(&zdr, pos); /* Look up the transaction in a hash table of our requests */ hash = rpc_hash_xid(xid); q = &rpc->waitpdu[hash]; /* Follow the hash chain. Linear traverse singly-linked list, * but track previous entry for optimised removal */ prev_pdu = NULL; for (pdu=q->head; pdu; pdu=pdu->next) { if (pdu->xid != xid) { prev_pdu = pdu; continue; } if (rpc->is_udp == 0 || rpc->is_broadcast == 0) { /* Singly-linked but we track head and tail */ if (pdu == q->head) q->head = pdu->next; if (pdu == q->tail) q->tail = prev_pdu; if (prev_pdu != NULL) prev_pdu->next = pdu->next; } if (rpc_process_reply(rpc, pdu, &zdr) != 0) { rpc_set_error(rpc, "rpc_procdess_reply failed"); } zdr_destroy(&zdr); if (rpc->is_udp == 0 || rpc->is_broadcast == 0) { rpc_free_pdu(rpc, pdu); } if (reasbuf != NULL) { free(reasbuf); } return 0; } rpc_set_error(rpc, "No matching pdu found for xid:%d", xid); zdr_destroy(&zdr); if (reasbuf != NULL) { free(reasbuf); } return -1; } libnfs-libnfs-1.9.8/lib/socket.c000066400000000000000000000416701255745034100165010ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #endif #ifdef HAVE_ARPA_INET_H #include #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #ifdef HAVE_SYS_IOCTL_H #include #endif #ifdef HAVE_SYS_SOCKET_H #include #endif #ifdef HAVE_NETINET_IN_H #include #endif #ifdef HAVE_NETINET_TCP_H #include #endif #ifdef HAVE_NETDB_H #include #endif #ifdef HAVE_SYS_FILIO_H #include #endif #ifdef HAVE_SYS_SOCKIO_H #include #endif #include #include #include #include #include #include #include #include #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" #include "slist.h" #ifdef WIN32 //has to be included after stdlib!! #include "win32_errnowrapper.h" #endif static int rpc_reconnect_requeue(struct rpc_context *rpc); static int rpc_connect_sockaddr_async(struct rpc_context *rpc, struct sockaddr_storage *s); static void set_nonblocking(int fd) { int v = 0; #if defined(WIN32) long nonblocking=1; v = ioctl(fd, FIONBIO, &nonblocking); #else v = fcntl(fd, F_GETFL, 0); fcntl(fd, F_SETFL, v | O_NONBLOCK); #endif //FIXME } static void set_nolinger(int fd) { struct linger lng; lng.l_onoff = 1; lng.l_linger = 0; setsockopt(fd, SOL_SOCKET, SO_LINGER, &lng, sizeof(lng)); } #ifdef HAVE_NETINET_TCP_H static int set_tcp_sockopt(int sockfd, int optname, int value) { int level; #if defined(__FreeBSD__) || defined(__sun) || (defined(__APPLE__) && defined(__MACH__)) struct protoent *buf; if ((buf = getprotobyname("tcp")) != NULL) level = buf->p_proto; else return -1; #else level = SOL_TCP; #endif return setsockopt(sockfd, level, optname, (char *)&value, sizeof(value)); } #endif int rpc_get_fd(struct rpc_context *rpc) { assert(rpc->magic == RPC_CONTEXT_MAGIC); return rpc->fd; } static int rpc_has_queue(struct rpc_queue *q) { return q->head != NULL; } int rpc_which_events(struct rpc_context *rpc) { int events; assert(rpc->magic == RPC_CONTEXT_MAGIC); events = rpc->is_connected ? POLLIN : POLLOUT; if (rpc->is_udp != 0) { /* for udp sockets we only wait for pollin */ return POLLIN; } if (rpc_has_queue(&rpc->outqueue)) { events |= POLLOUT; } return events; } static int rpc_write_to_socket(struct rpc_context *rpc) { int32_t count; struct rpc_pdu *pdu; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (rpc->fd == -1) { rpc_set_error(rpc, "trying to write but not connected"); return -1; } while ((pdu = rpc->outqueue.head) != NULL) { int64_t total; total = pdu->outdata.size; count = send(rpc->fd, pdu->outdata.data + pdu->written, total - pdu->written, 0); if (count == -1) { if (errno == EAGAIN || errno == EWOULDBLOCK) { return 0; } rpc_set_error(rpc, "Error when writing to socket :%s(%d)", strerror(errno), errno); return -1; } pdu->written += count; if (pdu->written == total) { unsigned int hash; rpc->outqueue.head = pdu->next; if (pdu->next == NULL) rpc->outqueue.tail = NULL; hash = rpc_hash_xid(pdu->xid); rpc_enqueue(&rpc->waitpdu[hash], pdu); } } return 0; } static int rpc_read_from_socket(struct rpc_context *rpc) { int size; int pdu_size; int32_t count; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (rpc->is_udp) { int available; socklen_t socklen = sizeof(rpc->udp_src); if (ioctl(rpc->fd, FIONREAD, &available) != 0) { rpc_set_error(rpc, "Ioctl FIONREAD returned error : %d. Closing socket.", errno); return -1; } if (available == 0) { rpc_set_error(rpc, "Socket has been closed"); return -1; } if (available > rpc->inbuflen) { rpc_set_error(rpc, "RPC fragment too big"); return -1; } count = recvfrom(rpc->fd, rpc->inbuf, available, MSG_DONTWAIT, (struct sockaddr *)&rpc->udp_src, &socklen); if (count < 0) { rpc_set_error(rpc, "Failed recvfrom: %s", strerror(errno)); return -1; } if (rpc_process_pdu(rpc, rpc->inbuf, count) != 0) { rpc_set_error(rpc, "Invalid/garbage pdu received from server. Ignoring PDU"); return -1; } return 0; } size = rpc->inbuflen - rpc->inpos; count = recv(rpc->fd, rpc->inbuf + rpc->inpos, size, MSG_DONTWAIT); if (count < 0) { if (errno == EINTR || errno == EAGAIN) { return 0; } rpc_set_error(rpc, "Read from socket failed, errno:%d. Closing socket.", errno); return -1; } rpc->inpos += count; while (rpc->inpos >= 4) { pdu_size = rpc_get_pdu_size(rpc->inbuf); if (pdu_size > NFS_MAX_XFER_SIZE + 4096) { rpc_set_error(rpc, "Incoming PDU exceeds limit of %d bytes.", NFS_MAX_XFER_SIZE + 4096); return -1; } if (rpc->inpos >= pdu_size) { if (rpc_process_pdu(rpc, rpc->inbuf, pdu_size) != 0) { rpc_set_error(rpc, "Invalid/garbage pdu received from server. Closing socket"); return -1; } memmove(rpc->inbuf, rpc->inbuf + pdu_size, rpc->inpos - pdu_size); rpc->inpos -= pdu_size; continue; } break; } return 0; } int rpc_service(struct rpc_context *rpc, int revents) { assert(rpc->magic == RPC_CONTEXT_MAGIC); if (revents & POLLERR) { #ifdef WIN32 char err = 0; #else int err = 0; #endif socklen_t err_size = sizeof(err); if (getsockopt(rpc->fd, SOL_SOCKET, SO_ERROR, (char *)&err, &err_size) != 0 || err != 0) { if (err == 0) { err = errno; } rpc_set_error(rpc, "rpc_service: socket error " "%s(%d).", strerror(err), err); } else { rpc_set_error(rpc, "rpc_service: POLLERR, " "Unknown socket error."); } if (rpc->connect_cb != NULL) { rpc->connect_cb(rpc, RPC_STATUS_ERROR, rpc->error_string, rpc->connect_data); } return -1; } if (revents & POLLHUP) { rpc_set_error(rpc, "Socket failed with POLLHUP"); if (rpc->connect_cb != NULL) { rpc->connect_cb(rpc, RPC_STATUS_ERROR, rpc->error_string, rpc->connect_data); } return -1; } if (rpc->is_connected == 0 && rpc->fd != -1 && revents&POLLOUT) { int err = 0; socklen_t err_size = sizeof(err); if (getsockopt(rpc->fd, SOL_SOCKET, SO_ERROR, (char *)&err, &err_size) != 0 || err != 0) { if (err == 0) { err = errno; } rpc_set_error(rpc, "rpc_service: socket error " "%s(%d) while connecting.", strerror(err), err); if (rpc->connect_cb != NULL) { rpc->connect_cb(rpc, RPC_STATUS_ERROR, NULL, rpc->connect_data); } return -1; } rpc->is_connected = 1; RPC_LOG(rpc, 2, "connection established"); if (rpc->connect_cb != NULL) { rpc->connect_cb(rpc, RPC_STATUS_SUCCESS, NULL, rpc->connect_data); } return 0; } if (revents & POLLIN) { if (rpc_read_from_socket(rpc) != 0) { rpc_reconnect_requeue(rpc); return 0; } } if (revents & POLLOUT && rpc_has_queue(&rpc->outqueue)) { if (rpc_write_to_socket(rpc) != 0) { rpc_set_error(rpc, "write to socket failed"); return -1; } } return 0; } void rpc_set_autoreconnect(struct rpc_context *rpc) { assert(rpc->magic == RPC_CONTEXT_MAGIC); rpc->auto_reconnect = 1; } void rpc_unset_autoreconnect(struct rpc_context *rpc) { assert(rpc->magic == RPC_CONTEXT_MAGIC); rpc->auto_reconnect = 0; } void rpc_set_tcp_syncnt(struct rpc_context *rpc, int v) { assert(rpc->magic == RPC_CONTEXT_MAGIC); rpc->tcp_syncnt = v; } #ifndef TCP_SYNCNT #define TCP_SYNCNT 7 #endif static int rpc_connect_sockaddr_async(struct rpc_context *rpc, struct sockaddr_storage *s) { int socksize; assert(rpc->magic == RPC_CONTEXT_MAGIC); switch (s->ss_family) { case AF_INET: socksize = sizeof(struct sockaddr_in); rpc->fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); #ifdef HAVE_NETINET_TCP_H if (rpc->tcp_syncnt != RPC_PARAM_UNDEFINED) { set_tcp_sockopt(rpc->fd, TCP_SYNCNT, rpc->tcp_syncnt); } #endif break; case AF_INET6: socksize = sizeof(struct sockaddr_in6); rpc->fd = socket(AF_INET6, SOCK_STREAM, IPPROTO_TCP); #ifdef HAVE_NETINET_TCP_H if (rpc->tcp_syncnt != RPC_PARAM_UNDEFINED) { set_tcp_sockopt(rpc->fd, TCP_SYNCNT, rpc->tcp_syncnt); } #endif break; default: rpc_set_error(rpc, "Can not handle AF_FAMILY:%d", s->ss_family); return -1; } if (rpc->fd == -1) { rpc_set_error(rpc, "Failed to open socket"); return -1; } /* Some systems allow you to set capabilities on an executable * to allow the file to be executed with privilege to bind to * privileged system ports, even if the user is not root. * * Opportunistically try to bind the socket to a low numbered * system port in the hope that the user is either root or the * executable has the CAP_NET_BIND_SERVICE. * * As soon as we fail the bind() with EACCES we know we will never * be able to bind to a system port so we terminate the loop. * * On linux, use * sudo setcap 'cap_net_bind_service=+ep' /path/executable * to make the executable able to bind to a system port. * * On Windows, there is no concept of privileged ports. Thus * binding will usually succeed. */ { struct sockaddr_storage ss; static int portOfs = 0; const int firstPort = 512; /* >= 512 according to Sun docs */ const int portCount = IPPORT_RESERVED - firstPort; int startOfs, port, rc; if (portOfs == 0) { portOfs = time(NULL) % 400; } startOfs = portOfs; do { rc = -1; port = htons(firstPort + portOfs); portOfs = (portOfs + 1) % portCount; /* skip well-known ports */ if (!getservbyport(port, "tcp")) { memset(&ss, 0, sizeof(ss)); switch (s->ss_family) { case AF_INET: ((struct sockaddr_in *)&ss)->sin_port = port; ((struct sockaddr_in *)&ss)->sin_family = AF_INET; #ifdef HAVE_SOCKADDR_LEN ((struct sockaddr_in *)&ss)->sin_len = sizeof(struct sockaddr_in); #endif break; case AF_INET6: ((struct sockaddr_in6 *)&ss)->sin6_port = port; ((struct sockaddr_in6 *)&ss)->sin6_family = AF_INET6; #ifdef HAVE_SOCKADDR_LEN ((struct sockaddr_in6 *)&ss)->sin6_len = sizeof(struct sockaddr_in6); #endif break; } rc = bind(rpc->fd, (struct sockaddr *)&ss, socksize); #if !defined(WIN32) /* we got EACCES, so don't try again */ if (rc != 0 && errno == EACCES) break; #endif } } while (rc != 0 && portOfs != startOfs); } set_nonblocking(rpc->fd); set_nolinger(rpc->fd); if (connect(rpc->fd, (struct sockaddr *)s, socksize) != 0 && errno != EINPROGRESS) { rpc_set_error(rpc, "connect() to server failed. %s(%d)", strerror(errno), errno); return -1; } return 0; } int rpc_connect_async(struct rpc_context *rpc, const char *server, int port, rpc_cb cb, void *private_data) { struct addrinfo *ai = NULL; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (rpc->fd != -1) { rpc_set_error(rpc, "Trying to connect while already connected"); return -1; } if (rpc->is_udp != 0) { rpc_set_error(rpc, "Trying to connect on UDP socket"); return -1; } rpc->auto_reconnect = 0; if (getaddrinfo(server, NULL, NULL, &ai) != 0) { rpc_set_error(rpc, "Invalid address:%s. " "Can not resolv into IPv4/v6 structure.", server); return -1; } switch (ai->ai_family) { case AF_INET: ((struct sockaddr_in *)&rpc->s)->sin_family = ai->ai_family; ((struct sockaddr_in *)&rpc->s)->sin_port = htons(port); ((struct sockaddr_in *)&rpc->s)->sin_addr = ((struct sockaddr_in *)(ai->ai_addr))->sin_addr; #ifdef HAVE_SOCKADDR_LEN ((struct sockaddr_in *)&rpc->s)->sin_len = sizeof(struct sockaddr_in); #endif break; case AF_INET6: ((struct sockaddr_in6 *)&rpc->s)->sin6_family = ai->ai_family; ((struct sockaddr_in6 *)&rpc->s)->sin6_port = htons(port); ((struct sockaddr_in6 *)&rpc->s)->sin6_addr = ((struct sockaddr_in6 *)(ai->ai_addr))->sin6_addr; #ifdef HAVE_SOCKADDR_LEN ((struct sockaddr_in6 *)&rpc->s)->sin6_len = sizeof(struct sockaddr_in6); #endif break; } rpc->connect_cb = cb; rpc->connect_data = private_data; freeaddrinfo(ai); if (rpc_connect_sockaddr_async(rpc, &rpc->s) != 0) { return -1; } return 0; } int rpc_disconnect(struct rpc_context *rpc, const char *error) { assert(rpc->magic == RPC_CONTEXT_MAGIC); rpc_unset_autoreconnect(rpc); if (rpc->fd != -1) { close(rpc->fd); } rpc->fd = -1; rpc->is_connected = 0; rpc_error_all_pdus(rpc, error); return 0; } static void reconnect_cb(struct rpc_context *rpc, int status, void *data _U_, void *private_data) { assert(rpc->magic == RPC_CONTEXT_MAGIC); if (status != RPC_STATUS_SUCCESS) { rpc_error_all_pdus(rpc, "RPC ERROR: Failed to reconnect async"); return; } rpc->is_connected = 1; rpc->connect_cb = NULL; } /* disconnect but do not error all PDUs, just move pdus in-flight back to the outqueue and reconnect */ static int rpc_reconnect_requeue(struct rpc_context *rpc) { struct rpc_pdu *pdu; unsigned int i; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (rpc->fd != -1) { close(rpc->fd); } rpc->fd = -1; rpc->is_connected = 0; rpc->inpos = 0; if (rpc->outqueue.head) { rpc->outqueue.head->written = 0; } /* socket is closed so we will not get any replies to any commands * in flight. Move them all over from the waitpdu queue back to the out queue */ for (i = 0; i < HASHES; i++) { struct rpc_queue *q = &rpc->waitpdu[i]; for (pdu=q->head; pdu; pdu=pdu->next) { rpc_return_to_queue(&rpc->outqueue, pdu); /* we have to re-send the whole pdu again */ pdu->written = 0; } rpc_reset_queue(q); } if (rpc->auto_reconnect != 0) { rpc->connect_cb = reconnect_cb; RPC_LOG(rpc, 1, "reconnect initiated"); if (rpc_connect_sockaddr_async(rpc, &rpc->s) != 0) { rpc_error_all_pdus(rpc, "RPC ERROR: Failed to reconnect async"); return -1; } } else { RPC_LOG(rpc, 1, "reconnect NOT initiated, auto-reconnect is disabled"); } return 0; } int rpc_bind_udp(struct rpc_context *rpc, char *addr, int port) { struct addrinfo *ai = NULL; char service[6]; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (rpc->is_udp == 0) { rpc_set_error(rpc, "Cant not bind UDP. Not UDP context"); return -1; } sprintf(service, "%d", port); if (getaddrinfo(addr, service, NULL, &ai) != 0) { rpc_set_error(rpc, "Invalid address:%s. " "Can not resolv into IPv4/v6 structure.", addr); return -1; } switch(ai->ai_family) { case AF_INET: rpc->fd = socket(ai->ai_family, SOCK_DGRAM, 0); if (rpc->fd == -1) { rpc_set_error(rpc, "Failed to create UDP socket: %s", strerror(errno)); freeaddrinfo(ai); return -1; } if (bind(rpc->fd, (struct sockaddr *)ai->ai_addr, sizeof(struct sockaddr_in)) != 0) { rpc_set_error(rpc, "Failed to bind to UDP socket: %s",strerror(errno)); freeaddrinfo(ai); return -1; } break; default: rpc_set_error(rpc, "Can not handle UPD sockets of family %d yet", ai->ai_family); freeaddrinfo(ai); return -1; } freeaddrinfo(ai); return 0; } int rpc_set_udp_destination(struct rpc_context *rpc, char *addr, int port, int is_broadcast) { struct addrinfo *ai = NULL; char service[6]; assert(rpc->magic == RPC_CONTEXT_MAGIC); if (rpc->is_udp == 0) { rpc_set_error(rpc, "Can not set destination sockaddr. Not UDP context"); return -1; } sprintf(service, "%d", port); if (getaddrinfo(addr, service, NULL, &ai) != 0) { rpc_set_error(rpc, "Invalid address:%s. " "Can not resolv into IPv4/v6 structure.", addr); return -1; } if (rpc->udp_dest) { free(rpc->udp_dest); rpc->udp_dest = NULL; } rpc->udp_dest = malloc(ai->ai_addrlen); if (rpc->udp_dest == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate sockaddr structure"); freeaddrinfo(ai); return -1; } memcpy(rpc->udp_dest, ai->ai_addr, ai->ai_addrlen); freeaddrinfo(ai); rpc->is_broadcast = is_broadcast; setsockopt(rpc->fd, SOL_SOCKET, SO_BROADCAST, (char *)&is_broadcast, sizeof(is_broadcast)); return 0; } struct sockaddr *rpc_get_recv_sockaddr(struct rpc_context *rpc) { assert(rpc->magic == RPC_CONTEXT_MAGIC); return (struct sockaddr *)&rpc->udp_src; } int rpc_queue_length(struct rpc_context *rpc) { int i=0; struct rpc_pdu *pdu; unsigned int n; assert(rpc->magic == RPC_CONTEXT_MAGIC); for(pdu = rpc->outqueue.head; pdu; pdu = pdu->next) { i++; } for (n = 0; n < HASHES; n++) { struct rpc_queue *q = &rpc->waitpdu[n]; for(pdu = q->head; pdu; pdu = pdu->next) i++; } return i; } void rpc_set_fd(struct rpc_context *rpc, int fd) { assert(rpc->magic == RPC_CONTEXT_MAGIC); rpc->fd = fd; } libnfs-libnfs-1.9.8/libnfs.pc.in000066400000000000000000000004431255745034100164760ustar00rootroot00000000000000# libnfs pkg-config file prefix=@prefix@ exec_prefix=@exec_prefix@ libdir=@libdir@ includedir=@includedir@ Name: libnfs Description: libnfs is a client library for accessing NFS shares over a network. Version: @VERSION@ Requires: Conflicts: Libs: -L${libdir} -lnfs Cflags: -I${includedir} libnfs-libnfs-1.9.8/mount/000077500000000000000000000000001255745034100154315ustar00rootroot00000000000000libnfs-libnfs-1.9.8/mount/Makefile.am000066400000000000000000000021011255745034100174570ustar00rootroot00000000000000noinst_LTLIBRARIES = libmount.la mount_SOURCES_GENERATED = mount_HEADERS_GENERATED = mount_GENERATED = $(mount_SOURCES_GENERATED) $(mount_HEADERS_GENERATED) CLEANFILES = $(mount_GENERATED) mount-stamp libmount_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc libmount_la_SOURCES = \ $(mount_SOURCES_GENERATED) \ mount.c libnfs-raw-mount.c libnfs-raw-mount.h $(mount_GENERATED) : mount-stamp mount-stamp : mount.x rm -f $(mount_GENERATED) touch mount-stamp compile_rpc: cat mount.x | head -29 >libnfs-raw-mount.h rpcgen -h mount.x | sed -e "s/#include /#include /" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" >> libnfs-raw-mount.h cat mount.x | head -29 >libnfs-raw-mount.c rpcgen -c mount.x | sed -e "s/#include \".*mount.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-mount.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-mount.c libnfs-libnfs-1.9.8/mount/libnfs-raw-mount.c000066400000000000000000000112161255745034100210020ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include "libnfs-zdr.h" #include "libnfs-raw-mount.h" uint32_t zdr_fhandle3 (ZDR *zdrs, fhandle3 *objp) { if (!zdr_bytes (zdrs, (char **)&objp->fhandle3_val, (u_int *) &objp->fhandle3_len, FHSIZE3)) return FALSE; return TRUE; } uint32_t zdr_dirpath (ZDR *zdrs, dirpath *objp) { if (!zdr_string (zdrs, objp, MNTPATHLEN)) return FALSE; return TRUE; } uint32_t zdr_name (ZDR *zdrs, name *objp) { if (!zdr_string (zdrs, objp, MNTNAMLEN)) return FALSE; return TRUE; } uint32_t zdr_mountstat3 (ZDR *zdrs, mountstat3 *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_mountlist (ZDR *zdrs, mountlist *objp) { if (!zdr_pointer (zdrs, (char **)objp, sizeof (struct mountbody), (zdrproc_t) zdr_mountbody)) return FALSE; return TRUE; } uint32_t zdr_mountbody (ZDR *zdrs, mountbody *objp) { if (!zdr_name (zdrs, &objp->ml_hostname)) return FALSE; if (!zdr_dirpath (zdrs, &objp->ml_directory)) return FALSE; if (!zdr_mountlist (zdrs, &objp->ml_next)) return FALSE; return TRUE; } uint32_t zdr_groups (ZDR *zdrs, groups *objp) { if (!zdr_pointer (zdrs, (char **)objp, sizeof (struct groupnode), (zdrproc_t) zdr_groupnode)) return FALSE; return TRUE; } uint32_t zdr_groupnode (ZDR *zdrs, groupnode *objp) { if (!zdr_name (zdrs, &objp->gr_name)) return FALSE; if (!zdr_groups (zdrs, &objp->gr_next)) return FALSE; return TRUE; } uint32_t zdr_exports (ZDR *zdrs, exports *objp) { if (!zdr_pointer (zdrs, (char **)objp, sizeof (struct exportnode), (zdrproc_t) zdr_exportnode)) return FALSE; return TRUE; } uint32_t zdr_exportnode (ZDR *zdrs, exportnode *objp) { if (!zdr_dirpath (zdrs, &objp->ex_dir)) return FALSE; if (!zdr_groups (zdrs, &objp->ex_groups)) return FALSE; if (!zdr_exports (zdrs, &objp->ex_next)) return FALSE; return TRUE; } uint32_t zdr_mountres3_ok (ZDR *zdrs, mountres3_ok *objp) { if (!zdr_fhandle3 (zdrs, &objp->fhandle)) return FALSE; if (!zdr_array (zdrs, (char **)&objp->auth_flavors.auth_flavors_val, (u_int *) &objp->auth_flavors.auth_flavors_len, ~0, sizeof (int), (zdrproc_t) zdr_int)) return FALSE; return TRUE; } uint32_t zdr_mountres3 (ZDR *zdrs, mountres3 *objp) { if (!zdr_mountstat3 (zdrs, &objp->fhs_status)) return FALSE; switch (objp->fhs_status) { case MNT3_OK: if (!zdr_mountres3_ok (zdrs, &objp->mountres3_u.mountinfo)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_mountstat1 (ZDR *zdrs, mountstat1 *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_fhandle1 (ZDR *zdrs, fhandle1 objp) { if (!zdr_opaque (zdrs, objp, FHSIZE)) return FALSE; return TRUE; } uint32_t zdr_mountres1_ok (ZDR *zdrs, mountres1_ok *objp) { if (!zdr_fhandle1 (zdrs, objp->fhandle)) return FALSE; return TRUE; } uint32_t zdr_mountres1 (ZDR *zdrs, mountres1 *objp) { if (!zdr_mountstat1 (zdrs, &objp->fhs_status)) return FALSE; switch (objp->fhs_status) { case MNT1_OK: if (!zdr_mountres1_ok (zdrs, &objp->mountres1_u.mountinfo)) return FALSE; break; default: break; } return TRUE; } libnfs-libnfs-1.9.8/mount/libnfs-raw-mount.h000066400000000000000000000200601255745034100210040ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _MOUNT_H_RPCGEN #define _MOUNT_H_RPCGEN #include #ifdef __cplusplus extern "C" { #endif #define MNTPATHLEN 1024 #define MNTNAMLEN 255 #define FHSIZE3 64 typedef struct { u_int fhandle3_len; char *fhandle3_val; } fhandle3; typedef char *dirpath; typedef char *name; enum mountstat3 { MNT3_OK = 0, MNT3ERR_PERM = 1, MNT3ERR_NOENT = 2, MNT3ERR_IO = 5, MNT3ERR_ACCES = 13, MNT3ERR_NOTDIR = 20, MNT3ERR_INVAL = 22, MNT3ERR_NAMETOOLONG = 63, MNT3ERR_NOTSUPP = 10004, MNT3ERR_SERVERFAULT = 10006, }; typedef enum mountstat3 mountstat3; typedef struct mountbody *mountlist; struct mountbody { name ml_hostname; dirpath ml_directory; mountlist ml_next; }; typedef struct mountbody mountbody; typedef struct groupnode *groups; struct groupnode { name gr_name; groups gr_next; }; typedef struct groupnode groupnode; typedef struct exportnode *exports; struct exportnode { dirpath ex_dir; groups ex_groups; exports ex_next; }; typedef struct exportnode exportnode; struct mountres3_ok { fhandle3 fhandle; struct { u_int auth_flavors_len; int *auth_flavors_val; } auth_flavors; }; typedef struct mountres3_ok mountres3_ok; struct mountres3 { mountstat3 fhs_status; union { mountres3_ok mountinfo; } mountres3_u; }; typedef struct mountres3 mountres3; enum mountstat1 { MNT1_OK = 0, MNT1ERR_PERM = 1, MNT1ERR_NOENT = 2, MNT1ERR_IO = 5, MNT1ERR_ACCES = 13, MNT1ERR_NOTDIR = 20, MNT1ERR_INVAL = 22, MNT1ERR_NAMETOOLONG = 63, MNT1ERR_NOTSUPP = 10004, MNT1ERR_SERVERFAULT = 10006, }; typedef enum mountstat1 mountstat1; #define FHSIZE 32 typedef char fhandle1[FHSIZE]; struct mountres1_ok { fhandle1 fhandle; }; typedef struct mountres1_ok mountres1_ok; struct mountres1 { mountstat1 fhs_status; union { mountres1_ok mountinfo; } mountres1_u; }; typedef struct mountres1 mountres1; #define MOUNT_PROGRAM 100005 #define MOUNT_V1 1 #if defined(__STDC__) || defined(__cplusplus) #define MOUNT1_NULL 0 extern void * mount1_null_1(void *, void *); extern void * mount1_null_1_svc(void *, struct svc_req *); #define MOUNT1_MNT 1 extern mountres1 * mount1_mnt_1(dirpath *, void *); extern mountres1 * mount1_mnt_1_svc(dirpath *, struct svc_req *); #define MOUNT1_DUMP 2 extern mountlist * mount1_dump_1(void *, void *); extern mountlist * mount1_dump_1_svc(void *, struct svc_req *); #define MOUNT1_UMNT 3 extern void * mount1_umnt_1(dirpath *, void *); extern void * mount1_umnt_1_svc(dirpath *, struct svc_req *); #define MOUNT1_UMNTALL 4 extern void * mount1_umntall_1(void *, void *); extern void * mount1_umntall_1_svc(void *, struct svc_req *); #define MOUNT1_EXPORT 5 extern exports * mount1_export_1(void *, void *); extern exports * mount1_export_1_svc(void *, struct svc_req *); extern int mount_program_1_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define MOUNT1_NULL 0 extern void * mount1_null_1(); extern void * mount1_null_1_svc(); #define MOUNT1_MNT 1 extern mountres1 * mount1_mnt_1(); extern mountres1 * mount1_mnt_1_svc(); #define MOUNT1_DUMP 2 extern mountlist * mount1_dump_1(); extern mountlist * mount1_dump_1_svc(); #define MOUNT1_UMNT 3 extern void * mount1_umnt_1(); extern void * mount1_umnt_1_svc(); #define MOUNT1_UMNTALL 4 extern void * mount1_umntall_1(); extern void * mount1_umntall_1_svc(); #define MOUNT1_EXPORT 5 extern exports * mount1_export_1(); extern exports * mount1_export_1_svc(); extern int mount_program_1_freeresult (); #endif /* K&R C */ #define MOUNT_V3 3 #if defined(__STDC__) || defined(__cplusplus) #define MOUNT3_NULL 0 extern void * mount3_null_3(void *, void *); extern void * mount3_null_3_svc(void *, struct svc_req *); #define MOUNT3_MNT 1 extern mountres3 * mount3_mnt_3(dirpath *, void *); extern mountres3 * mount3_mnt_3_svc(dirpath *, struct svc_req *); #define MOUNT3_DUMP 2 extern mountlist * mount3_dump_3(void *, void *); extern mountlist * mount3_dump_3_svc(void *, struct svc_req *); #define MOUNT3_UMNT 3 extern void * mount3_umnt_3(dirpath *, void *); extern void * mount3_umnt_3_svc(dirpath *, struct svc_req *); #define MOUNT3_UMNTALL 4 extern void * mount3_umntall_3(void *, void *); extern void * mount3_umntall_3_svc(void *, struct svc_req *); #define MOUNT3_EXPORT 5 extern exports * mount3_export_3(void *, void *); extern exports * mount3_export_3_svc(void *, struct svc_req *); extern int mount_program_3_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define MOUNT3_NULL 0 extern void * mount3_null_3(); extern void * mount3_null_3_svc(); #define MOUNT3_MNT 1 extern mountres3 * mount3_mnt_3(); extern mountres3 * mount3_mnt_3_svc(); #define MOUNT3_DUMP 2 extern mountlist * mount3_dump_3(); extern mountlist * mount3_dump_3_svc(); #define MOUNT3_UMNT 3 extern void * mount3_umnt_3(); extern void * mount3_umnt_3_svc(); #define MOUNT3_UMNTALL 4 extern void * mount3_umntall_3(); extern void * mount3_umntall_3_svc(); #define MOUNT3_EXPORT 5 extern exports * mount3_export_3(); extern exports * mount3_export_3_svc(); extern int mount_program_3_freeresult (); #endif /* K&R C */ /* the zdr functions */ #if defined(__STDC__) || defined(__cplusplus) extern uint32_t zdr_fhandle3 (ZDR *, fhandle3*); extern uint32_t zdr_dirpath (ZDR *, dirpath*); extern uint32_t zdr_name (ZDR *, name*); extern uint32_t zdr_mountstat3 (ZDR *, mountstat3*); extern uint32_t zdr_mountlist (ZDR *, mountlist*); extern uint32_t zdr_mountbody (ZDR *, mountbody*); extern uint32_t zdr_groups (ZDR *, groups*); extern uint32_t zdr_groupnode (ZDR *, groupnode*); extern uint32_t zdr_exports (ZDR *, exports*); extern uint32_t zdr_exportnode (ZDR *, exportnode*); extern uint32_t zdr_mountres3_ok (ZDR *, mountres3_ok*); extern uint32_t zdr_mountres3 (ZDR *, mountres3*); extern uint32_t zdr_mountstat1 (ZDR *, mountstat1*); extern uint32_t zdr_fhandle1 (ZDR *, fhandle1); extern uint32_t zdr_mountres1_ok (ZDR *, mountres1_ok*); extern uint32_t zdr_mountres1 (ZDR *, mountres1*); #else /* K&R C */ extern uint32_t zdr_fhandle3 (); extern uint32_t zdr_dirpath (); extern uint32_t zdr_name (); extern uint32_t zdr_mountstat3 (); extern uint32_t zdr_mountlist (); extern uint32_t zdr_mountbody (); extern uint32_t zdr_groups (); extern uint32_t zdr_groupnode (); extern uint32_t zdr_exports (); extern uint32_t zdr_exportnode (); extern uint32_t zdr_mountres3_ok (); extern uint32_t zdr_mountres3 (); extern uint32_t zdr_mountstat1 (); extern uint32_t zdr_fhandle1 (); extern uint32_t zdr_mountres1_ok (); extern uint32_t zdr_mountres1 (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_MOUNT_H_RPCGEN */ libnfs-libnfs-1.9.8/mount/mount.c000066400000000000000000000227121255745034100167430ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef WIN32 #include "win32_compat.h" #endif/*WIN32*/ #include #include #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" #include "libnfs-raw-mount.h" int rpc_mount3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for mount/null call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for mount/null call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { return rpc_mount3_null_async(rpc, cb, private_data); } int rpc_mount3_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_MNT, cb, private_data, (zdrproc_t)zdr_mountres3, sizeof(mountres3)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for mount/mnt call"); return -1; } if (zdr_dirpath(&pdu->zdr, &export) == 0) { rpc_set_error(rpc, "ZDR error. Failed to encode mount/mnt call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for mount/mnt call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) { return rpc_mount3_mnt_async(rpc, cb, export, private_data); } int rpc_mount3_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_DUMP, cb, private_data, (zdrproc_t)zdr_mountlist, sizeof(mountlist)); if (pdu == NULL) { rpc_set_error(rpc, "Failed to allocate pdu for mount/dump"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue mount/dump pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { return rpc_mount3_dump_async(rpc, cb, private_data); } int rpc_mount3_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_UMNT, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Failed to allocate pdu for mount/umnt"); return -1; } if (zdr_dirpath(&pdu->zdr, &export) == 0) { rpc_set_error(rpc, "failed to encode dirpath for mount/umnt"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue mount/umnt pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) { return rpc_mount3_umnt_async(rpc, cb, export, private_data); } int rpc_mount3_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_UMNTALL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Failed to allocate pdu for mount/umntall"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue mount/umntall pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { return rpc_mount3_umntall_async(rpc, cb, private_data); } int rpc_mount3_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V3, MOUNT3_EXPORT, cb, private_data, (zdrproc_t)zdr_exports, sizeof(exports)); if (pdu == NULL) { rpc_set_error(rpc, "Failed to allocate pdu for mount/export"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue mount/export pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { return rpc_mount3_export_async(rpc, cb, private_data); } char *mountstat3_to_str(int st) { enum mountstat3 stat = st; char *str = "unknown mount stat"; switch (stat) { case MNT3_OK: str="MNT3_OK"; break; case MNT3ERR_PERM: str="MNT3ERR_PERM"; break; case MNT3ERR_NOENT: str="MNT3ERR_NOENT"; break; case MNT3ERR_IO: str="MNT3ERR_IO"; break; case MNT3ERR_ACCES: str="MNT3ERR_ACCES"; break; case MNT3ERR_NOTDIR: str="MNT3ERR_NOTDIR"; break; case MNT3ERR_INVAL: str="MNT3ERR_INVAL"; break; case MNT3ERR_NAMETOOLONG: str="MNT3ERR_NAMETOOLONG"; break; case MNT3ERR_NOTSUPP: str="MNT3ERR_NOTSUPP"; break; case MNT3ERR_SERVERFAULT: str="MNT3ERR_SERVERFAULT"; break; } return str; } int mountstat3_to_errno(int st) { enum mountstat3 stat = st; switch (stat) { case MNT3_OK: return 0; break; case MNT3ERR_PERM: return -EPERM; break; case MNT3ERR_NOENT: return -EPERM; break; case MNT3ERR_IO: return -EIO; break; case MNT3ERR_ACCES: return -EACCES; break; case MNT3ERR_NOTDIR: return -ENOTDIR; break; case MNT3ERR_INVAL: return -EINVAL; break; case MNT3ERR_NAMETOOLONG: return -E2BIG; break; case MNT3ERR_NOTSUPP: return -EINVAL; break; case MNT3ERR_SERVERFAULT: return -EIO; break; } return -ERANGE; } int rpc_mount1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for MOUNT1/NULL call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for MOUNT1/NULL call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount1_mnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_MNT, cb, private_data, (zdrproc_t)zdr_mountres1, sizeof(mountres1)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for MOUNT1/MNT call"); return -1; } if (zdr_dirpath(&pdu->zdr, &export) == 0) { rpc_set_error(rpc, "ZDR error. Failed to encode MOUNT1/MNT call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for MOUNT1/MNT call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount1_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_DUMP, cb, private_data, (zdrproc_t)zdr_mountlist, sizeof(mountlist)); if (pdu == NULL) { rpc_set_error(rpc, "Failed to allocate pdu for MOUNT1/DUMP"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue MOUNT1/DUMP pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount1_umnt_async(struct rpc_context *rpc, rpc_cb cb, char *export, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_UMNT, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Failed to allocate pdu for MOUNT1/UMNT"); return -1; } if (zdr_dirpath(&pdu->zdr, &export) == 0) { rpc_set_error(rpc, "failed to encode dirpath for MOUNT1/UMNT"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue MOUNT1/UMNT pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount1_umntall_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_UMNTALL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Failed to allocate pdu for MOUNT1/UMNTALL"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue MOUNT1/UMNTALL pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_mount1_export_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, MOUNT_PROGRAM, MOUNT_V1, MOUNT1_EXPORT, cb, private_data, (zdrproc_t)zdr_exports, sizeof(exports)); if (pdu == NULL) { rpc_set_error(rpc, "Failed to allocate pdu for MOUNT1/EXPORT"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue MOUNT1/EXPORT pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } libnfs-libnfs-1.9.8/mount/mount.x000066400000000000000000000101601255745034100167620ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ const MNTPATHLEN = 1024; /* Maximum bytes in a path name */ const MNTNAMLEN = 255; /* Maximum bytes in a name */ const FHSIZE3 = 64; /* Maximum bytes in a V3 file handle */ typedef opaque fhandle3; typedef string dirpath; typedef string name; enum mountstat3 { MNT3_OK = 0, /* no error */ MNT3ERR_PERM = 1, /* Not owner */ MNT3ERR_NOENT = 2, /* No such file or directory */ MNT3ERR_IO = 5, /* I/O error */ MNT3ERR_ACCES = 13, /* Permission denied */ MNT3ERR_NOTDIR = 20, /* Not a directory */ MNT3ERR_INVAL = 22, /* Invalid argument */ MNT3ERR_NAMETOOLONG = 63, /* Filename too long */ MNT3ERR_NOTSUPP = 10004, /* Operation not supported */ MNT3ERR_SERVERFAULT = 10006 /* A failure on the server */ }; typedef struct mountbody *mountlist; struct mountbody { name ml_hostname; dirpath ml_directory; mountlist ml_next; }; typedef struct groupnode *groups; struct groupnode { name gr_name; groups gr_next; }; typedef struct exportnode *exports; struct exportnode { dirpath ex_dir; groups ex_groups; exports ex_next; }; struct mountres3_ok { fhandle3 fhandle; int auth_flavors<>; }; union mountres3 switch (mountstat3 fhs_status) { case MNT3_OK: mountres3_ok mountinfo; default: void; }; enum mountstat1 { MNT1_OK = 0, /* no error */ MNT1ERR_PERM = 1, /* Not owner */ MNT1ERR_NOENT = 2, /* No such file or directory */ MNT1ERR_IO = 5, /* I/O error */ MNT1ERR_ACCES = 13, /* Permission denied */ MNT1ERR_NOTDIR = 20, /* Not a directory */ MNT1ERR_INVAL = 22, /* Invalid argument */ MNT1ERR_NAMETOOLONG = 63, /* Filename too long */ MNT1ERR_NOTSUPP = 10004, /* Operation not supported */ MNT1ERR_SERVERFAULT = 10006 /* A failure on the server */ }; const FHSIZE = 32; typedef opaque fhandle1[FHSIZE]; struct mountres1_ok { fhandle1 fhandle; }; union mountres1 switch (mountstat1 fhs_status) { case MNT1_OK: mountres1_ok mountinfo; default: void; }; program MOUNT_PROGRAM { version MOUNT_V1 { void MOUNT1_NULL(void) = 0; mountres1 MOUNT1_MNT(dirpath) = 1; mountlist MOUNT1_DUMP(void) = 2; void MOUNT1_UMNT(dirpath) = 3; void MOUNT1_UMNTALL(void) = 4; exports MOUNT1_EXPORT(void) = 5; } = 1; version MOUNT_V3 { void MOUNT3_NULL(void) = 0; mountres3 MOUNT3_MNT(dirpath) = 1; mountlist MOUNT3_DUMP(void) = 2; void MOUNT3_UMNT(dirpath) = 3; void MOUNT3_UMNTALL(void) = 4; exports MOUNT3_EXPORT(void) = 5; } = 3; } = 100005; libnfs-libnfs-1.9.8/nfs/000077500000000000000000000000001255745034100150555ustar00rootroot00000000000000libnfs-libnfs-1.9.8/nfs/Makefile.am000066400000000000000000000022441255745034100171130ustar00rootroot00000000000000noinst_LTLIBRARIES = libnfs.la nfs_SOURCES_GENERATED = nfs_HEADERS_GENERATED = nfs_GENERATED = $(nfs_SOURCES_GENERATED) $(nfs_HEADERS_GENERATED) CLEANFILES = $(nfs_GENERATED) nfs-stamp libnfs_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc libnfs_la_SOURCES = \ $(nfs_SOURCES_GENERATED) \ nfs.c nfsacl.c libnfs-raw-nfs.c libnfs-raw-nfs.h $(nfs_GENERATED) : nfs-stamp nfs-stamp : nfs.x rm -f $(nfs_GENERATED) touch nfs-stamp compile_rpc: cat nfs.x | head -29 >libnfs-raw-nfs.h rpcgen -h nfs.x | sed -e "s/#include /#include /" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/#define _NFS_H_RPCGEN/#define _NFS_H_RPCGEN\n#include /g" -e "s/#define NFS3_COOKIEVERFSIZE 8/#define NFS3_COOKIEVERFSIZE 8\n\n/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nfs.h cat nfs.x | head -29 >libnfs-raw-nfs.c rpcgen -c nfs.x | sed -e "s/#include \".*nfs.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-nfs.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nfs.c libnfs-libnfs-1.9.8/nfs/libnfs-raw-nfs.c000066400000000000000000001576261255745034100200720ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include "libnfs-zdr.h" #include "libnfs-raw-nfs.h" uint32_t zdr_cookieverf3 (ZDR *zdrs, cookieverf3 objp) { if (!zdr_opaque (zdrs, objp, NFS3_COOKIEVERFSIZE)) return FALSE; return TRUE; } uint32_t zdr_cookie3 (ZDR *zdrs, cookie3 *objp) { if (!zdr_uint64_t (zdrs, objp)) return FALSE; return TRUE; } uint32_t zdr_nfs_fh3 (ZDR *zdrs, nfs_fh3 *objp) { if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, NFS3_FHSIZE)) return FALSE; return TRUE; } uint32_t zdr_filename3 (ZDR *zdrs, filename3 *objp) { if (!zdr_string (zdrs, objp, ~0)) return FALSE; return TRUE; } uint32_t zdr_diropargs3 (ZDR *zdrs, diropargs3 *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->dir)) return FALSE; if (!zdr_filename3 (zdrs, &objp->name)) return FALSE; return TRUE; } uint32_t zdr_ftype3 (ZDR *zdrs, ftype3 *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_mode3 (ZDR *zdrs, mode3 *objp) { if (!zdr_u_int (zdrs, objp)) return FALSE; return TRUE; } uint32_t zdr_uid3 (ZDR *zdrs, uid3 *objp) { if (!zdr_u_int (zdrs, objp)) return FALSE; return TRUE; } uint32_t zdr_gid3 (ZDR *zdrs, gid3 *objp) { if (!zdr_u_int (zdrs, objp)) return FALSE; return TRUE; } uint32_t zdr_size3 (ZDR *zdrs, size3 *objp) { if (!zdr_uint64_t (zdrs, objp)) return FALSE; return TRUE; } uint32_t zdr_fileid3 (ZDR *zdrs, fileid3 *objp) { if (!zdr_uint64_t (zdrs, objp)) return FALSE; return TRUE; } uint32_t zdr_specdata3 (ZDR *zdrs, specdata3 *objp) { if (!zdr_u_int (zdrs, &objp->specdata1)) return FALSE; if (!zdr_u_int (zdrs, &objp->specdata2)) return FALSE; return TRUE; } uint32_t zdr_nfstime3 (ZDR *zdrs, nfstime3 *objp) { if (!zdr_u_int (zdrs, &objp->seconds)) return FALSE; if (!zdr_u_int (zdrs, &objp->nseconds)) return FALSE; return TRUE; } uint32_t zdr_fattr3 (ZDR *zdrs, fattr3 *objp) { if (!zdr_ftype3 (zdrs, &objp->type)) return FALSE; if (!zdr_mode3 (zdrs, &objp->mode)) return FALSE; if (!zdr_u_int (zdrs, &objp->nlink)) return FALSE; if (!zdr_uid3 (zdrs, &objp->uid)) return FALSE; if (!zdr_gid3 (zdrs, &objp->gid)) return FALSE; if (!zdr_size3 (zdrs, &objp->size)) return FALSE; if (!zdr_size3 (zdrs, &objp->used)) return FALSE; if (!zdr_specdata3 (zdrs, &objp->rdev)) return FALSE; if (!zdr_uint64_t (zdrs, &objp->fsid)) return FALSE; if (!zdr_fileid3 (zdrs, &objp->fileid)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->atime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->mtime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->ctime)) return FALSE; return TRUE; } uint32_t zdr_post_op_attr (ZDR *zdrs, post_op_attr *objp) { if (!zdr_bool (zdrs, &objp->attributes_follow)) return FALSE; switch (objp->attributes_follow) { case TRUE: if (!zdr_fattr3 (zdrs, &objp->post_op_attr_u.attributes)) return FALSE; break; case FALSE: break; default: return FALSE; } return TRUE; } uint32_t zdr_nfsstat3 (ZDR *zdrs, nfsstat3 *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_stable_how (ZDR *zdrs, stable_how *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_offset3 (ZDR *zdrs, offset3 *objp) { if (!zdr_uint64_t (zdrs, objp)) return FALSE; return TRUE; } uint32_t zdr_count3 (ZDR *zdrs, count3 *objp) { if (!zdr_u_int (zdrs, objp)) return FALSE; return TRUE; } uint32_t zdr_wcc_attr (ZDR *zdrs, wcc_attr *objp) { if (!zdr_size3 (zdrs, &objp->size)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->mtime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->ctime)) return FALSE; return TRUE; } uint32_t zdr_pre_op_attr (ZDR *zdrs, pre_op_attr *objp) { if (!zdr_bool (zdrs, &objp->attributes_follow)) return FALSE; switch (objp->attributes_follow) { case TRUE: if (!zdr_wcc_attr (zdrs, &objp->pre_op_attr_u.attributes)) return FALSE; break; case FALSE: break; default: return FALSE; } return TRUE; } uint32_t zdr_wcc_data (ZDR *zdrs, wcc_data *objp) { if (!zdr_pre_op_attr (zdrs, &objp->before)) return FALSE; if (!zdr_post_op_attr (zdrs, &objp->after)) return FALSE; return TRUE; } uint32_t zdr_WRITE3args (ZDR *zdrs, WRITE3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->file)) return FALSE; if (!zdr_offset3 (zdrs, &objp->offset)) return FALSE; if (!zdr_count3 (zdrs, &objp->count)) return FALSE; if (!zdr_stable_how (zdrs, &objp->stable)) return FALSE; if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) return FALSE; return TRUE; } uint32_t zdr_writeverf3 (ZDR *zdrs, writeverf3 objp) { if (!zdr_opaque (zdrs, objp, NFS3_WRITEVERFSIZE)) return FALSE; return TRUE; } uint32_t zdr_WRITE3resok (ZDR *zdrs, WRITE3resok *objp) { if (!zdr_wcc_data (zdrs, &objp->file_wcc)) return FALSE; if (!zdr_count3 (zdrs, &objp->count)) return FALSE; if (!zdr_stable_how (zdrs, &objp->committed)) return FALSE; if (!zdr_writeverf3 (zdrs, objp->verf)) return FALSE; return TRUE; } uint32_t zdr_WRITE3resfail (ZDR *zdrs, WRITE3resfail *objp) { if (!zdr_wcc_data (zdrs, &objp->file_wcc)) return FALSE; return TRUE; } uint32_t zdr_WRITE3res (ZDR *zdrs, WRITE3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_WRITE3resok (zdrs, &objp->WRITE3res_u.resok)) return FALSE; break; default: if (!zdr_WRITE3resfail (zdrs, &objp->WRITE3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_LOOKUP3args (ZDR *zdrs, LOOKUP3args *objp) { if (!zdr_diropargs3 (zdrs, &objp->what)) return FALSE; return TRUE; } uint32_t zdr_LOOKUP3resok (ZDR *zdrs, LOOKUP3resok *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->object)) return FALSE; if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) return FALSE; return TRUE; } uint32_t zdr_LOOKUP3resfail (ZDR *zdrs, LOOKUP3resfail *objp) { if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) return FALSE; return TRUE; } uint32_t zdr_LOOKUP3res (ZDR *zdrs, LOOKUP3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_LOOKUP3resok (zdrs, &objp->LOOKUP3res_u.resok)) return FALSE; break; default: if (!zdr_LOOKUP3resfail (zdrs, &objp->LOOKUP3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_COMMIT3args (ZDR *zdrs, COMMIT3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->file)) return FALSE; if (!zdr_offset3 (zdrs, &objp->offset)) return FALSE; if (!zdr_count3 (zdrs, &objp->count)) return FALSE; return TRUE; } uint32_t zdr_COMMIT3resok (ZDR *zdrs, COMMIT3resok *objp) { if (!zdr_wcc_data (zdrs, &objp->file_wcc)) return FALSE; if (!zdr_writeverf3 (zdrs, objp->verf)) return FALSE; return TRUE; } uint32_t zdr_COMMIT3resfail (ZDR *zdrs, COMMIT3resfail *objp) { if (!zdr_wcc_data (zdrs, &objp->file_wcc)) return FALSE; return TRUE; } uint32_t zdr_COMMIT3res (ZDR *zdrs, COMMIT3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_COMMIT3resok (zdrs, &objp->COMMIT3res_u.resok)) return FALSE; break; default: if (!zdr_COMMIT3resfail (zdrs, &objp->COMMIT3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_ACCESS3args (ZDR *zdrs, ACCESS3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->object)) return FALSE; if (!zdr_u_int (zdrs, &objp->access)) return FALSE; return TRUE; } uint32_t zdr_ACCESS3resok (ZDR *zdrs, ACCESS3resok *objp) { if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; if (!zdr_u_int (zdrs, &objp->access)) return FALSE; return TRUE; } uint32_t zdr_ACCESS3resfail (ZDR *zdrs, ACCESS3resfail *objp) { if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; return TRUE; } uint32_t zdr_ACCESS3res (ZDR *zdrs, ACCESS3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_ACCESS3resok (zdrs, &objp->ACCESS3res_u.resok)) return FALSE; break; default: if (!zdr_ACCESS3resfail (zdrs, &objp->ACCESS3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_GETATTR3args (ZDR *zdrs, GETATTR3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->object)) return FALSE; return TRUE; } uint32_t zdr_GETATTR3resok (ZDR *zdrs, GETATTR3resok *objp) { if (!zdr_fattr3 (zdrs, &objp->obj_attributes)) return FALSE; return TRUE; } uint32_t zdr_GETATTR3res (ZDR *zdrs, GETATTR3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_GETATTR3resok (zdrs, &objp->GETATTR3res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_time_how (ZDR *zdrs, time_how *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_set_mode3 (ZDR *zdrs, set_mode3 *objp) { if (!zdr_bool (zdrs, &objp->set_it)) return FALSE; switch (objp->set_it) { case TRUE: if (!zdr_mode3 (zdrs, &objp->set_mode3_u.mode)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_set_uid3 (ZDR *zdrs, set_uid3 *objp) { if (!zdr_bool (zdrs, &objp->set_it)) return FALSE; switch (objp->set_it) { case TRUE: if (!zdr_uid3 (zdrs, &objp->set_uid3_u.uid)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_set_gid3 (ZDR *zdrs, set_gid3 *objp) { if (!zdr_bool (zdrs, &objp->set_it)) return FALSE; switch (objp->set_it) { case TRUE: if (!zdr_gid3 (zdrs, &objp->set_gid3_u.gid)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_set_size3 (ZDR *zdrs, set_size3 *objp) { if (!zdr_bool (zdrs, &objp->set_it)) return FALSE; switch (objp->set_it) { case TRUE: if (!zdr_size3 (zdrs, &objp->set_size3_u.size)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_set_atime (ZDR *zdrs, set_atime *objp) { if (!zdr_time_how (zdrs, &objp->set_it)) return FALSE; switch (objp->set_it) { case SET_TO_CLIENT_TIME: if (!zdr_nfstime3 (zdrs, &objp->set_atime_u.atime)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_set_mtime (ZDR *zdrs, set_mtime *objp) { if (!zdr_time_how (zdrs, &objp->set_it)) return FALSE; switch (objp->set_it) { case SET_TO_CLIENT_TIME: if (!zdr_nfstime3 (zdrs, &objp->set_mtime_u.mtime)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_sattr3 (ZDR *zdrs, sattr3 *objp) { if (!zdr_set_mode3 (zdrs, &objp->mode)) return FALSE; if (!zdr_set_uid3 (zdrs, &objp->uid)) return FALSE; if (!zdr_set_gid3 (zdrs, &objp->gid)) return FALSE; if (!zdr_set_size3 (zdrs, &objp->size)) return FALSE; if (!zdr_set_atime (zdrs, &objp->atime)) return FALSE; if (!zdr_set_mtime (zdrs, &objp->mtime)) return FALSE; return TRUE; } uint32_t zdr_createmode3 (ZDR *zdrs, createmode3 *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_createverf3 (ZDR *zdrs, createverf3 objp) { if (!zdr_opaque (zdrs, objp, NFS3_CREATEVERFSIZE)) return FALSE; return TRUE; } uint32_t zdr_createhow3 (ZDR *zdrs, createhow3 *objp) { if (!zdr_createmode3 (zdrs, &objp->mode)) return FALSE; switch (objp->mode) { case UNCHECKED: if (!zdr_sattr3 (zdrs, &objp->createhow3_u.obj_attributes)) return FALSE; break; case GUARDED: if (!zdr_sattr3 (zdrs, &objp->createhow3_u.g_obj_attributes)) return FALSE; break; case EXCLUSIVE: if (!zdr_createverf3 (zdrs, objp->createhow3_u.verf)) return FALSE; break; default: return FALSE; } return TRUE; } uint32_t zdr_CREATE3args (ZDR *zdrs, CREATE3args *objp) { if (!zdr_diropargs3 (zdrs, &objp->where)) return FALSE; if (!zdr_createhow3 (zdrs, &objp->how)) return FALSE; return TRUE; } uint32_t zdr_post_op_fh3 (ZDR *zdrs, post_op_fh3 *objp) { if (!zdr_bool (zdrs, &objp->handle_follows)) return FALSE; switch (objp->handle_follows) { case TRUE: if (!zdr_nfs_fh3 (zdrs, &objp->post_op_fh3_u.handle)) return FALSE; break; case FALSE: break; default: return FALSE; } return TRUE; } uint32_t zdr_CREATE3resok (ZDR *zdrs, CREATE3resok *objp) { if (!zdr_post_op_fh3 (zdrs, &objp->obj)) return FALSE; if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_CREATE3resfail (ZDR *zdrs, CREATE3resfail *objp) { if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_CREATE3res (ZDR *zdrs, CREATE3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_CREATE3resok (zdrs, &objp->CREATE3res_u.resok)) return FALSE; break; default: if (!zdr_CREATE3resfail (zdrs, &objp->CREATE3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_REMOVE3args (ZDR *zdrs, REMOVE3args *objp) { if (!zdr_diropargs3 (zdrs, &objp->object)) return FALSE; return TRUE; } uint32_t zdr_REMOVE3resok (ZDR *zdrs, REMOVE3resok *objp) { if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_REMOVE3resfail (ZDR *zdrs, REMOVE3resfail *objp) { if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_REMOVE3res (ZDR *zdrs, REMOVE3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_REMOVE3resok (zdrs, &objp->REMOVE3res_u.resok)) return FALSE; break; default: if (!zdr_REMOVE3resfail (zdrs, &objp->REMOVE3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_READ3args (ZDR *zdrs, READ3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->file)) return FALSE; if (!zdr_offset3 (zdrs, &objp->offset)) return FALSE; if (!zdr_count3 (zdrs, &objp->count)) return FALSE; return TRUE; } uint32_t zdr_READ3resok (ZDR *zdrs, READ3resok *objp) { if (!zdr_post_op_attr (zdrs, &objp->file_attributes)) return FALSE; if (!zdr_count3 (zdrs, &objp->count)) return FALSE; if (!zdr_bool (zdrs, &objp->eof)) return FALSE; if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) return FALSE; return TRUE; } uint32_t zdr_READ3resfail (ZDR *zdrs, READ3resfail *objp) { if (!zdr_post_op_attr (zdrs, &objp->file_attributes)) return FALSE; return TRUE; } uint32_t zdr_READ3res (ZDR *zdrs, READ3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_READ3resok (zdrs, &objp->READ3res_u.resok)) return FALSE; break; default: if (!zdr_READ3resfail (zdrs, &objp->READ3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_FSINFO3args (ZDR *zdrs, FSINFO3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->fsroot)) return FALSE; return TRUE; } uint32_t zdr_FSINFO3resok (ZDR *zdrs, FSINFO3resok *objp) { register int32_t *buf; buf = NULL; if (zdrs->x_op == ZDR_ENCODE) { if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; buf = ZDR_INLINE (zdrs, 7 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->rtmax)) return FALSE; if (!zdr_u_int (zdrs, &objp->rtpref)) return FALSE; if (!zdr_u_int (zdrs, &objp->rtmult)) return FALSE; if (!zdr_u_int (zdrs, &objp->wtmax)) return FALSE; if (!zdr_u_int (zdrs, &objp->wtpref)) return FALSE; if (!zdr_u_int (zdrs, &objp->wtmult)) return FALSE; if (!zdr_u_int (zdrs, &objp->dtpref)) return FALSE; } else { IZDR_PUT_U_LONG(buf, objp->rtmax); IZDR_PUT_U_LONG(buf, objp->rtpref); IZDR_PUT_U_LONG(buf, objp->rtmult); IZDR_PUT_U_LONG(buf, objp->wtmax); IZDR_PUT_U_LONG(buf, objp->wtpref); IZDR_PUT_U_LONG(buf, objp->wtmult); IZDR_PUT_U_LONG(buf, objp->dtpref); } if (!zdr_size3 (zdrs, &objp->maxfilesize)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->time_delta)) return FALSE; if (!zdr_u_int (zdrs, &objp->properties)) return FALSE; return TRUE; } else if (zdrs->x_op == ZDR_DECODE) { if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; buf = ZDR_INLINE (zdrs, 7 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->rtmax)) return FALSE; if (!zdr_u_int (zdrs, &objp->rtpref)) return FALSE; if (!zdr_u_int (zdrs, &objp->rtmult)) return FALSE; if (!zdr_u_int (zdrs, &objp->wtmax)) return FALSE; if (!zdr_u_int (zdrs, &objp->wtpref)) return FALSE; if (!zdr_u_int (zdrs, &objp->wtmult)) return FALSE; if (!zdr_u_int (zdrs, &objp->dtpref)) return FALSE; } else { objp->rtmax = IZDR_GET_U_LONG(buf); objp->rtpref = IZDR_GET_U_LONG(buf); objp->rtmult = IZDR_GET_U_LONG(buf); objp->wtmax = IZDR_GET_U_LONG(buf); objp->wtpref = IZDR_GET_U_LONG(buf); objp->wtmult = IZDR_GET_U_LONG(buf); objp->dtpref = IZDR_GET_U_LONG(buf); } if (!zdr_size3 (zdrs, &objp->maxfilesize)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->time_delta)) return FALSE; if (!zdr_u_int (zdrs, &objp->properties)) return FALSE; return TRUE; } if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; if (!zdr_u_int (zdrs, &objp->rtmax)) return FALSE; if (!zdr_u_int (zdrs, &objp->rtpref)) return FALSE; if (!zdr_u_int (zdrs, &objp->rtmult)) return FALSE; if (!zdr_u_int (zdrs, &objp->wtmax)) return FALSE; if (!zdr_u_int (zdrs, &objp->wtpref)) return FALSE; if (!zdr_u_int (zdrs, &objp->wtmult)) return FALSE; if (!zdr_u_int (zdrs, &objp->dtpref)) return FALSE; if (!zdr_size3 (zdrs, &objp->maxfilesize)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->time_delta)) return FALSE; if (!zdr_u_int (zdrs, &objp->properties)) return FALSE; return TRUE; } uint32_t zdr_FSINFO3resfail (ZDR *zdrs, FSINFO3resfail *objp) { if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; return TRUE; } uint32_t zdr_FSINFO3res (ZDR *zdrs, FSINFO3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_FSINFO3resok (zdrs, &objp->FSINFO3res_u.resok)) return FALSE; break; default: if (!zdr_FSINFO3resfail (zdrs, &objp->FSINFO3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_FSSTAT3args (ZDR *zdrs, FSSTAT3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->fsroot)) return FALSE; return TRUE; } uint32_t zdr_FSSTAT3resok (ZDR *zdrs, FSSTAT3resok *objp) { if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; if (!zdr_size3 (zdrs, &objp->tbytes)) return FALSE; if (!zdr_size3 (zdrs, &objp->fbytes)) return FALSE; if (!zdr_size3 (zdrs, &objp->abytes)) return FALSE; if (!zdr_size3 (zdrs, &objp->tfiles)) return FALSE; if (!zdr_size3 (zdrs, &objp->ffiles)) return FALSE; if (!zdr_size3 (zdrs, &objp->afiles)) return FALSE; if (!zdr_u_int (zdrs, &objp->invarsec)) return FALSE; return TRUE; } uint32_t zdr_FSSTAT3resfail (ZDR *zdrs, FSSTAT3resfail *objp) { if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; return TRUE; } uint32_t zdr_FSSTAT3res (ZDR *zdrs, FSSTAT3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_FSSTAT3resok (zdrs, &objp->FSSTAT3res_u.resok)) return FALSE; break; default: if (!zdr_FSSTAT3resfail (zdrs, &objp->FSSTAT3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_PATHCONF3args (ZDR *zdrs, PATHCONF3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->object)) return FALSE; return TRUE; } uint32_t zdr_PATHCONF3resok (ZDR *zdrs, PATHCONF3resok *objp) { register int32_t *buf; buf = NULL; if (zdrs->x_op == ZDR_ENCODE) { if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; buf = ZDR_INLINE (zdrs, 6 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->linkmax)) return FALSE; if (!zdr_u_int (zdrs, &objp->name_max)) return FALSE; if (!zdr_bool (zdrs, &objp->no_trunc)) return FALSE; if (!zdr_bool (zdrs, &objp->chown_restricted)) return FALSE; if (!zdr_bool (zdrs, &objp->case_insensitive)) return FALSE; if (!zdr_bool (zdrs, &objp->case_preserving)) return FALSE; } else { IZDR_PUT_U_LONG(buf, objp->linkmax); IZDR_PUT_U_LONG(buf, objp->name_max); IZDR_PUT_BOOL(buf, objp->no_trunc); IZDR_PUT_BOOL(buf, objp->chown_restricted); IZDR_PUT_BOOL(buf, objp->case_insensitive); IZDR_PUT_BOOL(buf, objp->case_preserving); } return TRUE; } else if (zdrs->x_op == ZDR_DECODE) { if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; buf = ZDR_INLINE (zdrs, 6 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->linkmax)) return FALSE; if (!zdr_u_int (zdrs, &objp->name_max)) return FALSE; if (!zdr_bool (zdrs, &objp->no_trunc)) return FALSE; if (!zdr_bool (zdrs, &objp->chown_restricted)) return FALSE; if (!zdr_bool (zdrs, &objp->case_insensitive)) return FALSE; if (!zdr_bool (zdrs, &objp->case_preserving)) return FALSE; } else { objp->linkmax = IZDR_GET_U_LONG(buf); objp->name_max = IZDR_GET_U_LONG(buf); objp->no_trunc = IZDR_GET_BOOL(buf); objp->chown_restricted = IZDR_GET_BOOL(buf); objp->case_insensitive = IZDR_GET_BOOL(buf); objp->case_preserving = IZDR_GET_BOOL(buf); } return TRUE; } if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; if (!zdr_u_int (zdrs, &objp->linkmax)) return FALSE; if (!zdr_u_int (zdrs, &objp->name_max)) return FALSE; if (!zdr_bool (zdrs, &objp->no_trunc)) return FALSE; if (!zdr_bool (zdrs, &objp->chown_restricted)) return FALSE; if (!zdr_bool (zdrs, &objp->case_insensitive)) return FALSE; if (!zdr_bool (zdrs, &objp->case_preserving)) return FALSE; return TRUE; } uint32_t zdr_PATHCONF3resfail (ZDR *zdrs, PATHCONF3resfail *objp) { if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; return TRUE; } uint32_t zdr_PATHCONF3res (ZDR *zdrs, PATHCONF3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_PATHCONF3resok (zdrs, &objp->PATHCONF3res_u.resok)) return FALSE; break; default: if (!zdr_PATHCONF3resfail (zdrs, &objp->PATHCONF3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_nfspath3 (ZDR *zdrs, nfspath3 *objp) { if (!zdr_string (zdrs, objp, ~0)) return FALSE; return TRUE; } uint32_t zdr_symlinkdata3 (ZDR *zdrs, symlinkdata3 *objp) { if (!zdr_sattr3 (zdrs, &objp->symlink_attributes)) return FALSE; if (!zdr_nfspath3 (zdrs, &objp->symlink_data)) return FALSE; return TRUE; } uint32_t zdr_SYMLINK3args (ZDR *zdrs, SYMLINK3args *objp) { if (!zdr_diropargs3 (zdrs, &objp->where)) return FALSE; if (!zdr_symlinkdata3 (zdrs, &objp->symlink)) return FALSE; return TRUE; } uint32_t zdr_SYMLINK3resok (ZDR *zdrs, SYMLINK3resok *objp) { if (!zdr_post_op_fh3 (zdrs, &objp->obj)) return FALSE; if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_SYMLINK3resfail (ZDR *zdrs, SYMLINK3resfail *objp) { if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_SYMLINK3res (ZDR *zdrs, SYMLINK3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_SYMLINK3resok (zdrs, &objp->SYMLINK3res_u.resok)) return FALSE; break; default: if (!zdr_SYMLINK3resfail (zdrs, &objp->SYMLINK3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_READLINK3args (ZDR *zdrs, READLINK3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->symlink)) return FALSE; return TRUE; } uint32_t zdr_READLINK3resok (ZDR *zdrs, READLINK3resok *objp) { if (!zdr_post_op_attr (zdrs, &objp->symlink_attributes)) return FALSE; if (!zdr_nfspath3 (zdrs, &objp->data)) return FALSE; return TRUE; } uint32_t zdr_READLINK3resfail (ZDR *zdrs, READLINK3resfail *objp) { if (!zdr_post_op_attr (zdrs, &objp->symlink_attributes)) return FALSE; return TRUE; } uint32_t zdr_READLINK3res (ZDR *zdrs, READLINK3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_READLINK3resok (zdrs, &objp->READLINK3res_u.resok)) return FALSE; break; default: if (!zdr_READLINK3resfail (zdrs, &objp->READLINK3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_devicedata3 (ZDR *zdrs, devicedata3 *objp) { if (!zdr_sattr3 (zdrs, &objp->dev_attributes)) return FALSE; if (!zdr_specdata3 (zdrs, &objp->spec)) return FALSE; return TRUE; } uint32_t zdr_mknoddata3 (ZDR *zdrs, mknoddata3 *objp) { if (!zdr_ftype3 (zdrs, &objp->type)) return FALSE; switch (objp->type) { case NF3CHR: if (!zdr_devicedata3 (zdrs, &objp->mknoddata3_u.chr_device)) return FALSE; break; case NF3BLK: if (!zdr_devicedata3 (zdrs, &objp->mknoddata3_u.blk_device)) return FALSE; break; case NF3SOCK: if (!zdr_sattr3 (zdrs, &objp->mknoddata3_u.sock_attributes)) return FALSE; break; case NF3FIFO: if (!zdr_sattr3 (zdrs, &objp->mknoddata3_u.pipe_attributes)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_MKNOD3args (ZDR *zdrs, MKNOD3args *objp) { if (!zdr_diropargs3 (zdrs, &objp->where)) return FALSE; if (!zdr_mknoddata3 (zdrs, &objp->what)) return FALSE; return TRUE; } uint32_t zdr_MKNOD3resok (ZDR *zdrs, MKNOD3resok *objp) { if (!zdr_post_op_fh3 (zdrs, &objp->obj)) return FALSE; if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_MKNOD3resfail (ZDR *zdrs, MKNOD3resfail *objp) { if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_MKNOD3res (ZDR *zdrs, MKNOD3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_MKNOD3resok (zdrs, &objp->MKNOD3res_u.resok)) return FALSE; break; default: if (!zdr_MKNOD3resfail (zdrs, &objp->MKNOD3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_MKDIR3args (ZDR *zdrs, MKDIR3args *objp) { if (!zdr_diropargs3 (zdrs, &objp->where)) return FALSE; if (!zdr_sattr3 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_MKDIR3resok (ZDR *zdrs, MKDIR3resok *objp) { if (!zdr_post_op_fh3 (zdrs, &objp->obj)) return FALSE; if (!zdr_post_op_attr (zdrs, &objp->obj_attributes)) return FALSE; if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_MKDIR3resfail (ZDR *zdrs, MKDIR3resfail *objp) { if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_MKDIR3res (ZDR *zdrs, MKDIR3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_MKDIR3resok (zdrs, &objp->MKDIR3res_u.resok)) return FALSE; break; default: if (!zdr_MKDIR3resfail (zdrs, &objp->MKDIR3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_RMDIR3args (ZDR *zdrs, RMDIR3args *objp) { if (!zdr_diropargs3 (zdrs, &objp->object)) return FALSE; return TRUE; } uint32_t zdr_RMDIR3resok (ZDR *zdrs, RMDIR3resok *objp) { if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_RMDIR3resfail (ZDR *zdrs, RMDIR3resfail *objp) { if (!zdr_wcc_data (zdrs, &objp->dir_wcc)) return FALSE; return TRUE; } uint32_t zdr_RMDIR3res (ZDR *zdrs, RMDIR3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_RMDIR3resok (zdrs, &objp->RMDIR3res_u.resok)) return FALSE; break; default: if (!zdr_RMDIR3resfail (zdrs, &objp->RMDIR3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_RENAME3args (ZDR *zdrs, RENAME3args *objp) { if (!zdr_diropargs3 (zdrs, &objp->from)) return FALSE; if (!zdr_diropargs3 (zdrs, &objp->to)) return FALSE; return TRUE; } uint32_t zdr_RENAME3resok (ZDR *zdrs, RENAME3resok *objp) { if (!zdr_wcc_data (zdrs, &objp->fromdir_wcc)) return FALSE; if (!zdr_wcc_data (zdrs, &objp->todir_wcc)) return FALSE; return TRUE; } uint32_t zdr_RENAME3resfail (ZDR *zdrs, RENAME3resfail *objp) { if (!zdr_wcc_data (zdrs, &objp->fromdir_wcc)) return FALSE; if (!zdr_wcc_data (zdrs, &objp->todir_wcc)) return FALSE; return TRUE; } uint32_t zdr_RENAME3res (ZDR *zdrs, RENAME3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_RENAME3resok (zdrs, &objp->RENAME3res_u.resok)) return FALSE; break; default: if (!zdr_RENAME3resfail (zdrs, &objp->RENAME3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_READDIRPLUS3args (ZDR *zdrs, READDIRPLUS3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->dir)) return FALSE; if (!zdr_cookie3 (zdrs, &objp->cookie)) return FALSE; if (!zdr_cookieverf3 (zdrs, objp->cookieverf)) return FALSE; if (!zdr_count3 (zdrs, &objp->dircount)) return FALSE; if (!zdr_count3 (zdrs, &objp->maxcount)) return FALSE; return TRUE; } uint32_t zdr_entryplus3 (ZDR *zdrs, entryplus3 *objp) { if (!zdr_fileid3 (zdrs, &objp->fileid)) return FALSE; if (!zdr_filename3 (zdrs, &objp->name)) return FALSE; if (!zdr_cookie3 (zdrs, &objp->cookie)) return FALSE; if (!zdr_post_op_attr (zdrs, &objp->name_attributes)) return FALSE; if (!zdr_post_op_fh3 (zdrs, &objp->name_handle)) return FALSE; if (!zdr_pointer (zdrs, (char **)&objp->nextentry, sizeof (entryplus3), (zdrproc_t) zdr_entryplus3)) return FALSE; return TRUE; } uint32_t zdr_dirlistplus3 (ZDR *zdrs, dirlistplus3 *objp) { if (!zdr_pointer (zdrs, (char **)&objp->entries, sizeof (entryplus3), (zdrproc_t) zdr_entryplus3)) return FALSE; if (!zdr_bool (zdrs, &objp->eof)) return FALSE; return TRUE; } uint32_t zdr_READDIRPLUS3resok (ZDR *zdrs, READDIRPLUS3resok *objp) { if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) return FALSE; if (!zdr_cookieverf3 (zdrs, objp->cookieverf)) return FALSE; if (!zdr_dirlistplus3 (zdrs, &objp->reply)) return FALSE; return TRUE; } uint32_t zdr_READDIRPLUS3resfail (ZDR *zdrs, READDIRPLUS3resfail *objp) { if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) return FALSE; return TRUE; } uint32_t zdr_READDIRPLUS3res (ZDR *zdrs, READDIRPLUS3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_READDIRPLUS3resok (zdrs, &objp->READDIRPLUS3res_u.resok)) return FALSE; break; default: if (!zdr_READDIRPLUS3resfail (zdrs, &objp->READDIRPLUS3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_READDIR3args (ZDR *zdrs, READDIR3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->dir)) return FALSE; if (!zdr_cookie3 (zdrs, &objp->cookie)) return FALSE; if (!zdr_cookieverf3 (zdrs, objp->cookieverf)) return FALSE; if (!zdr_count3 (zdrs, &objp->count)) return FALSE; return TRUE; } uint32_t zdr_entry3 (ZDR *zdrs, entry3 *objp) { if (!zdr_fileid3 (zdrs, &objp->fileid)) return FALSE; if (!zdr_filename3 (zdrs, &objp->name)) return FALSE; if (!zdr_cookie3 (zdrs, &objp->cookie)) return FALSE; if (!zdr_pointer (zdrs, (char **)&objp->nextentry, sizeof (entry3), (zdrproc_t) zdr_entry3)) return FALSE; return TRUE; } uint32_t zdr_dirlist3 (ZDR *zdrs, dirlist3 *objp) { if (!zdr_pointer (zdrs, (char **)&objp->entries, sizeof (entry3), (zdrproc_t) zdr_entry3)) return FALSE; if (!zdr_bool (zdrs, &objp->eof)) return FALSE; return TRUE; } uint32_t zdr_READDIR3resok (ZDR *zdrs, READDIR3resok *objp) { if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) return FALSE; if (!zdr_cookieverf3 (zdrs, objp->cookieverf)) return FALSE; if (!zdr_dirlist3 (zdrs, &objp->reply)) return FALSE; return TRUE; } uint32_t zdr_READDIR3resfail (ZDR *zdrs, READDIR3resfail *objp) { if (!zdr_post_op_attr (zdrs, &objp->dir_attributes)) return FALSE; return TRUE; } uint32_t zdr_READDIR3res (ZDR *zdrs, READDIR3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_READDIR3resok (zdrs, &objp->READDIR3res_u.resok)) return FALSE; break; default: if (!zdr_READDIR3resfail (zdrs, &objp->READDIR3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_LINK3args (ZDR *zdrs, LINK3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->file)) return FALSE; if (!zdr_diropargs3 (zdrs, &objp->link)) return FALSE; return TRUE; } uint32_t zdr_LINK3resok (ZDR *zdrs, LINK3resok *objp) { if (!zdr_post_op_attr (zdrs, &objp->file_attributes)) return FALSE; if (!zdr_wcc_data (zdrs, &objp->linkdir_wcc)) return FALSE; return TRUE; } uint32_t zdr_LINK3resfail (ZDR *zdrs, LINK3resfail *objp) { if (!zdr_post_op_attr (zdrs, &objp->file_attributes)) return FALSE; if (!zdr_wcc_data (zdrs, &objp->linkdir_wcc)) return FALSE; return TRUE; } uint32_t zdr_LINK3res (ZDR *zdrs, LINK3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_LINK3resok (zdrs, &objp->LINK3res_u.resok)) return FALSE; break; default: if (!zdr_LINK3resfail (zdrs, &objp->LINK3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_sattrguard3 (ZDR *zdrs, sattrguard3 *objp) { if (!zdr_bool (zdrs, &objp->check)) return FALSE; switch (objp->check) { case TRUE: if (!zdr_nfstime3 (zdrs, &objp->sattrguard3_u.obj_ctime)) return FALSE; break; case FALSE: break; default: return FALSE; } return TRUE; } uint32_t zdr_SETATTR3args (ZDR *zdrs, SETATTR3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->object)) return FALSE; if (!zdr_sattr3 (zdrs, &objp->new_attributes)) return FALSE; if (!zdr_sattrguard3 (zdrs, &objp->guard)) return FALSE; return TRUE; } uint32_t zdr_SETATTR3resok (ZDR *zdrs, SETATTR3resok *objp) { if (!zdr_wcc_data (zdrs, &objp->obj_wcc)) return FALSE; return TRUE; } uint32_t zdr_SETATTR3resfail (ZDR *zdrs, SETATTR3resfail *objp) { if (!zdr_wcc_data (zdrs, &objp->obj_wcc)) return FALSE; return TRUE; } uint32_t zdr_SETATTR3res (ZDR *zdrs, SETATTR3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_SETATTR3resok (zdrs, &objp->SETATTR3res_u.resok)) return FALSE; break; default: if (!zdr_SETATTR3resfail (zdrs, &objp->SETATTR3res_u.resfail)) return FALSE; break; } return TRUE; } uint32_t zdr_fhandle2 (ZDR *zdrs, fhandle2 objp) { if (!zdr_opaque (zdrs, objp, FHSIZE2)) return FALSE; return TRUE; } uint32_t zdr_ftype2 (ZDR *zdrs, ftype2 *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_fattr2 (ZDR *zdrs, fattr2 *objp) { register int32_t *buf; buf = NULL; if (zdrs->x_op == ZDR_ENCODE) { if (!zdr_ftype2 (zdrs, &objp->type)) return FALSE; buf = ZDR_INLINE (zdrs, 10 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->mode)) return FALSE; if (!zdr_u_int (zdrs, &objp->nlink)) return FALSE; if (!zdr_u_int (zdrs, &objp->uid)) return FALSE; if (!zdr_u_int (zdrs, &objp->gid)) return FALSE; if (!zdr_u_int (zdrs, &objp->size)) return FALSE; if (!zdr_u_int (zdrs, &objp->blocksize)) return FALSE; if (!zdr_u_int (zdrs, &objp->rdev)) return FALSE; if (!zdr_u_int (zdrs, &objp->blocks)) return FALSE; if (!zdr_u_int (zdrs, &objp->fsid)) return FALSE; if (!zdr_u_int (zdrs, &objp->fileid)) return FALSE; } else { IZDR_PUT_U_LONG(buf, objp->mode); IZDR_PUT_U_LONG(buf, objp->nlink); IZDR_PUT_U_LONG(buf, objp->uid); IZDR_PUT_U_LONG(buf, objp->gid); IZDR_PUT_U_LONG(buf, objp->size); IZDR_PUT_U_LONG(buf, objp->blocksize); IZDR_PUT_U_LONG(buf, objp->rdev); IZDR_PUT_U_LONG(buf, objp->blocks); IZDR_PUT_U_LONG(buf, objp->fsid); IZDR_PUT_U_LONG(buf, objp->fileid); } if (!zdr_nfstime3 (zdrs, &objp->atime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->mtime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->ctime)) return FALSE; return TRUE; } else if (zdrs->x_op == ZDR_DECODE) { if (!zdr_ftype2 (zdrs, &objp->type)) return FALSE; buf = ZDR_INLINE (zdrs, 10 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->mode)) return FALSE; if (!zdr_u_int (zdrs, &objp->nlink)) return FALSE; if (!zdr_u_int (zdrs, &objp->uid)) return FALSE; if (!zdr_u_int (zdrs, &objp->gid)) return FALSE; if (!zdr_u_int (zdrs, &objp->size)) return FALSE; if (!zdr_u_int (zdrs, &objp->blocksize)) return FALSE; if (!zdr_u_int (zdrs, &objp->rdev)) return FALSE; if (!zdr_u_int (zdrs, &objp->blocks)) return FALSE; if (!zdr_u_int (zdrs, &objp->fsid)) return FALSE; if (!zdr_u_int (zdrs, &objp->fileid)) return FALSE; } else { objp->mode = IZDR_GET_U_LONG(buf); objp->nlink = IZDR_GET_U_LONG(buf); objp->uid = IZDR_GET_U_LONG(buf); objp->gid = IZDR_GET_U_LONG(buf); objp->size = IZDR_GET_U_LONG(buf); objp->blocksize = IZDR_GET_U_LONG(buf); objp->rdev = IZDR_GET_U_LONG(buf); objp->blocks = IZDR_GET_U_LONG(buf); objp->fsid = IZDR_GET_U_LONG(buf); objp->fileid = IZDR_GET_U_LONG(buf); } if (!zdr_nfstime3 (zdrs, &objp->atime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->mtime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->ctime)) return FALSE; return TRUE; } if (!zdr_ftype2 (zdrs, &objp->type)) return FALSE; if (!zdr_u_int (zdrs, &objp->mode)) return FALSE; if (!zdr_u_int (zdrs, &objp->nlink)) return FALSE; if (!zdr_u_int (zdrs, &objp->uid)) return FALSE; if (!zdr_u_int (zdrs, &objp->gid)) return FALSE; if (!zdr_u_int (zdrs, &objp->size)) return FALSE; if (!zdr_u_int (zdrs, &objp->blocksize)) return FALSE; if (!zdr_u_int (zdrs, &objp->rdev)) return FALSE; if (!zdr_u_int (zdrs, &objp->blocks)) return FALSE; if (!zdr_u_int (zdrs, &objp->fsid)) return FALSE; if (!zdr_u_int (zdrs, &objp->fileid)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->atime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->mtime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->ctime)) return FALSE; return TRUE; } uint32_t zdr_sattr2 (ZDR *zdrs, sattr2 *objp) { register int32_t *buf; buf = NULL; if (zdrs->x_op == ZDR_ENCODE) { buf = ZDR_INLINE (zdrs, 4 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->mode)) return FALSE; if (!zdr_u_int (zdrs, &objp->uid)) return FALSE; if (!zdr_u_int (zdrs, &objp->gid)) return FALSE; if (!zdr_u_int (zdrs, &objp->size)) return FALSE; } else { IZDR_PUT_U_LONG(buf, objp->mode); IZDR_PUT_U_LONG(buf, objp->uid); IZDR_PUT_U_LONG(buf, objp->gid); IZDR_PUT_U_LONG(buf, objp->size); } if (!zdr_nfstime3 (zdrs, &objp->atime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->mtime)) return FALSE; return TRUE; } else if (zdrs->x_op == ZDR_DECODE) { buf = ZDR_INLINE (zdrs, 4 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->mode)) return FALSE; if (!zdr_u_int (zdrs, &objp->uid)) return FALSE; if (!zdr_u_int (zdrs, &objp->gid)) return FALSE; if (!zdr_u_int (zdrs, &objp->size)) return FALSE; } else { objp->mode = IZDR_GET_U_LONG(buf); objp->uid = IZDR_GET_U_LONG(buf); objp->gid = IZDR_GET_U_LONG(buf); objp->size = IZDR_GET_U_LONG(buf); } if (!zdr_nfstime3 (zdrs, &objp->atime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->mtime)) return FALSE; return TRUE; } if (!zdr_u_int (zdrs, &objp->mode)) return FALSE; if (!zdr_u_int (zdrs, &objp->uid)) return FALSE; if (!zdr_u_int (zdrs, &objp->gid)) return FALSE; if (!zdr_u_int (zdrs, &objp->size)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->atime)) return FALSE; if (!zdr_nfstime3 (zdrs, &objp->mtime)) return FALSE; return TRUE; } uint32_t zdr_filename2 (ZDR *zdrs, filename2 *objp) { if (!zdr_string (zdrs, objp, MAXNAMLEN2)) return FALSE; return TRUE; } uint32_t zdr_path2 (ZDR *zdrs, path2 *objp) { if (!zdr_string (zdrs, objp, MAXPATHLEN2)) return FALSE; return TRUE; } uint32_t zdr_nfsdata2 (ZDR *zdrs, nfsdata2 *objp) { if (!zdr_bytes (zdrs, (char **)&objp->nfsdata2_val, (u_int *) &objp->nfsdata2_len, NFSMAXDATA2)) return FALSE; return TRUE; } uint32_t zdr_nfscookie2 (ZDR *zdrs, nfscookie2 objp) { if (!zdr_opaque (zdrs, objp, NFSCOOKIESIZE2)) return FALSE; return TRUE; } uint32_t zdr_entry2 (ZDR *zdrs, entry2 *objp) { if (!zdr_u_int (zdrs, &objp->fileid)) return FALSE; if (!zdr_filename2 (zdrs, &objp->name)) return FALSE; if (!zdr_nfscookie2 (zdrs, objp->cookie)) return FALSE; if (!zdr_pointer (zdrs, (char **)&objp->nextentry, sizeof (entry2), (zdrproc_t) zdr_entry2)) return FALSE; return TRUE; } uint32_t zdr_diropargs2 (ZDR *zdrs, diropargs2 *objp) { if (!zdr_fhandle2 (zdrs, objp->dir)) return FALSE; if (!zdr_filename2 (zdrs, &objp->name)) return FALSE; return TRUE; } uint32_t zdr_GETATTR2args (ZDR *zdrs, GETATTR2args *objp) { if (!zdr_fhandle2 (zdrs, objp->fhandle)) return FALSE; return TRUE; } uint32_t zdr_GETATTR2resok (ZDR *zdrs, GETATTR2resok *objp) { if (!zdr_fattr2 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_GETATTR2res (ZDR *zdrs, GETATTR2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_GETATTR2resok (zdrs, &objp->GETATTR2res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_SETATTR2args (ZDR *zdrs, SETATTR2args *objp) { if (!zdr_fhandle2 (zdrs, objp->fhandle)) return FALSE; if (!zdr_sattr2 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_SETATTR2resok (ZDR *zdrs, SETATTR2resok *objp) { if (!zdr_fattr2 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_SETATTR2res (ZDR *zdrs, SETATTR2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_SETATTR2resok (zdrs, &objp->SETATTR2res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_LOOKUP2args (ZDR *zdrs, LOOKUP2args *objp) { if (!zdr_diropargs2 (zdrs, &objp->what)) return FALSE; return TRUE; } uint32_t zdr_LOOKUP2resok (ZDR *zdrs, LOOKUP2resok *objp) { if (!zdr_fhandle2 (zdrs, objp->file)) return FALSE; if (!zdr_fattr2 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_LOOKUP2res (ZDR *zdrs, LOOKUP2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_LOOKUP2resok (zdrs, &objp->LOOKUP2res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_READLINK2args (ZDR *zdrs, READLINK2args *objp) { if (!zdr_fhandle2 (zdrs, objp->file)) return FALSE; return TRUE; } uint32_t zdr_READLINK2resok (ZDR *zdrs, READLINK2resok *objp) { if (!zdr_path2 (zdrs, &objp->data)) return FALSE; return TRUE; } uint32_t zdr_READLINK2res (ZDR *zdrs, READLINK2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_READLINK2resok (zdrs, &objp->READLINK2res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_READ2args (ZDR *zdrs, READ2args *objp) { if (!zdr_fhandle2 (zdrs, objp->file)) return FALSE; if (!zdr_u_int (zdrs, &objp->offset)) return FALSE; if (!zdr_u_int (zdrs, &objp->count)) return FALSE; if (!zdr_u_int (zdrs, &objp->totalcount)) return FALSE; return TRUE; } uint32_t zdr_READ2resok (ZDR *zdrs, READ2resok *objp) { if (!zdr_fattr2 (zdrs, &objp->attributes)) return FALSE; if (!zdr_nfsdata2 (zdrs, &objp->data)) return FALSE; return TRUE; } uint32_t zdr_READ2res (ZDR *zdrs, READ2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_READ2resok (zdrs, &objp->READ2res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_WRITE2args (ZDR *zdrs, WRITE2args *objp) { register int32_t *buf; buf = NULL; if (zdrs->x_op == ZDR_ENCODE) { if (!zdr_fhandle2 (zdrs, objp->file)) return FALSE; buf = ZDR_INLINE (zdrs, 3 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->beginoffset)) return FALSE; if (!zdr_u_int (zdrs, &objp->offset)) return FALSE; if (!zdr_u_int (zdrs, &objp->totalcount)) return FALSE; } else { IZDR_PUT_U_LONG(buf, objp->beginoffset); IZDR_PUT_U_LONG(buf, objp->offset); IZDR_PUT_U_LONG(buf, objp->totalcount); } if (!zdr_nfsdata2 (zdrs, &objp->data)) return FALSE; return TRUE; } else if (zdrs->x_op == ZDR_DECODE) { if (!zdr_fhandle2 (zdrs, objp->file)) return FALSE; buf = ZDR_INLINE (zdrs, 3 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->beginoffset)) return FALSE; if (!zdr_u_int (zdrs, &objp->offset)) return FALSE; if (!zdr_u_int (zdrs, &objp->totalcount)) return FALSE; } else { objp->beginoffset = IZDR_GET_U_LONG(buf); objp->offset = IZDR_GET_U_LONG(buf); objp->totalcount = IZDR_GET_U_LONG(buf); } if (!zdr_nfsdata2 (zdrs, &objp->data)) return FALSE; return TRUE; } if (!zdr_fhandle2 (zdrs, objp->file)) return FALSE; if (!zdr_u_int (zdrs, &objp->beginoffset)) return FALSE; if (!zdr_u_int (zdrs, &objp->offset)) return FALSE; if (!zdr_u_int (zdrs, &objp->totalcount)) return FALSE; if (!zdr_nfsdata2 (zdrs, &objp->data)) return FALSE; return TRUE; } uint32_t zdr_WRITE2resok (ZDR *zdrs, WRITE2resok *objp) { if (!zdr_fattr2 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_WRITE2res (ZDR *zdrs, WRITE2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_WRITE2resok (zdrs, &objp->WRITE2res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_CREATE2args (ZDR *zdrs, CREATE2args *objp) { if (!zdr_diropargs2 (zdrs, &objp->where)) return FALSE; if (!zdr_sattr2 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_CREATE2resok (ZDR *zdrs, CREATE2resok *objp) { if (!zdr_fhandle2 (zdrs, objp->file)) return FALSE; if (!zdr_fattr2 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_CREATE2res (ZDR *zdrs, CREATE2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_CREATE2resok (zdrs, &objp->CREATE2res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_REMOVE2args (ZDR *zdrs, REMOVE2args *objp) { if (!zdr_diropargs2 (zdrs, &objp->what)) return FALSE; return TRUE; } uint32_t zdr_REMOVE2res (ZDR *zdrs, REMOVE2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; return TRUE; } uint32_t zdr_RENAME2args (ZDR *zdrs, RENAME2args *objp) { if (!zdr_diropargs2 (zdrs, &objp->from)) return FALSE; if (!zdr_diropargs2 (zdrs, &objp->to)) return FALSE; return TRUE; } uint32_t zdr_RENAME2res (ZDR *zdrs, RENAME2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; return TRUE; } uint32_t zdr_LINK2args (ZDR *zdrs, LINK2args *objp) { if (!zdr_fhandle2 (zdrs, objp->from)) return FALSE; if (!zdr_diropargs2 (zdrs, &objp->to)) return FALSE; return TRUE; } uint32_t zdr_LINK2res (ZDR *zdrs, LINK2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; return TRUE; } uint32_t zdr_SYMLINK2args (ZDR *zdrs, SYMLINK2args *objp) { if (!zdr_diropargs2 (zdrs, &objp->from)) return FALSE; if (!zdr_path2 (zdrs, &objp->to)) return FALSE; if (!zdr_sattr2 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_SYMLINK2res (ZDR *zdrs, SYMLINK2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; return TRUE; } uint32_t zdr_MKDIR2args (ZDR *zdrs, MKDIR2args *objp) { if (!zdr_diropargs2 (zdrs, &objp->where)) return FALSE; if (!zdr_sattr2 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_MKDIR2resok (ZDR *zdrs, MKDIR2resok *objp) { if (!zdr_fhandle2 (zdrs, objp->file)) return FALSE; if (!zdr_fattr2 (zdrs, &objp->attributes)) return FALSE; return TRUE; } uint32_t zdr_MKDIR2res (ZDR *zdrs, MKDIR2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_MKDIR2resok (zdrs, &objp->MKDIR2res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_RMDIR2args (ZDR *zdrs, RMDIR2args *objp) { if (!zdr_diropargs2 (zdrs, &objp->what)) return FALSE; return TRUE; } uint32_t zdr_RMDIR2res (ZDR *zdrs, RMDIR2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; return TRUE; } uint32_t zdr_READDIR2args (ZDR *zdrs, READDIR2args *objp) { if (!zdr_fhandle2 (zdrs, objp->dir)) return FALSE; if (!zdr_nfscookie2 (zdrs, objp->cookie)) return FALSE; if (!zdr_u_int (zdrs, &objp->count)) return FALSE; return TRUE; } uint32_t zdr_READDIR2resok (ZDR *zdrs, READDIR2resok *objp) { if (!zdr_pointer (zdrs, (char **)&objp->entries, sizeof (entry2), (zdrproc_t) zdr_entry2)) return FALSE; if (!zdr_bool (zdrs, &objp->eof)) return FALSE; return TRUE; } uint32_t zdr_READDIR2res (ZDR *zdrs, READDIR2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_READDIR2resok (zdrs, &objp->READDIR2res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_STATFS2args (ZDR *zdrs, STATFS2args *objp) { if (!zdr_fhandle2 (zdrs, objp->dir)) return FALSE; return TRUE; } uint32_t zdr_STATFS2resok (ZDR *zdrs, STATFS2resok *objp) { register int32_t *buf; buf = NULL; if (zdrs->x_op == ZDR_ENCODE) { buf = ZDR_INLINE (zdrs, 5 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->tsize)) return FALSE; if (!zdr_u_int (zdrs, &objp->bsize)) return FALSE; if (!zdr_u_int (zdrs, &objp->blocks)) return FALSE; if (!zdr_u_int (zdrs, &objp->bfree)) return FALSE; if (!zdr_u_int (zdrs, &objp->bavail)) return FALSE; } else { IZDR_PUT_U_LONG(buf, objp->tsize); IZDR_PUT_U_LONG(buf, objp->bsize); IZDR_PUT_U_LONG(buf, objp->blocks); IZDR_PUT_U_LONG(buf, objp->bfree); IZDR_PUT_U_LONG(buf, objp->bavail); } return TRUE; } else if (zdrs->x_op == ZDR_DECODE) { buf = ZDR_INLINE (zdrs, 5 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->tsize)) return FALSE; if (!zdr_u_int (zdrs, &objp->bsize)) return FALSE; if (!zdr_u_int (zdrs, &objp->blocks)) return FALSE; if (!zdr_u_int (zdrs, &objp->bfree)) return FALSE; if (!zdr_u_int (zdrs, &objp->bavail)) return FALSE; } else { objp->tsize = IZDR_GET_U_LONG(buf); objp->bsize = IZDR_GET_U_LONG(buf); objp->blocks = IZDR_GET_U_LONG(buf); objp->bfree = IZDR_GET_U_LONG(buf); objp->bavail = IZDR_GET_U_LONG(buf); } return TRUE; } if (!zdr_u_int (zdrs, &objp->tsize)) return FALSE; if (!zdr_u_int (zdrs, &objp->bsize)) return FALSE; if (!zdr_u_int (zdrs, &objp->blocks)) return FALSE; if (!zdr_u_int (zdrs, &objp->bfree)) return FALSE; if (!zdr_u_int (zdrs, &objp->bavail)) return FALSE; return TRUE; } uint32_t zdr_STATFS2res (ZDR *zdrs, STATFS2res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_STATFS2resok (zdrs, &objp->STATFS2res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_nfsacl_type (ZDR *zdrs, nfsacl_type *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_nfsacl_ace (ZDR *zdrs, nfsacl_ace *objp) { if (!zdr_nfsacl_type (zdrs, &objp->type)) return FALSE; if (!zdr_u_int (zdrs, &objp->id)) return FALSE; if (!zdr_u_int (zdrs, &objp->perm)) return FALSE; return TRUE; } uint32_t zdr_GETACL3args (ZDR *zdrs, GETACL3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->dir)) return FALSE; if (!zdr_u_int (zdrs, &objp->mask)) return FALSE; return TRUE; } uint32_t zdr_GETACL3resok (ZDR *zdrs, GETACL3resok *objp) { if (!zdr_post_op_attr (zdrs, &objp->attr)) return FALSE; if (!zdr_u_int (zdrs, &objp->mask)) return FALSE; if (!zdr_u_int (zdrs, &objp->ace_count)) return FALSE; if (!zdr_array (zdrs, (char **)&objp->ace.ace_val, (u_int *) &objp->ace.ace_len, ~0, sizeof (nfsacl_ace), (zdrproc_t) zdr_nfsacl_ace)) return FALSE; if (!zdr_u_int (zdrs, &objp->default_ace_count)) return FALSE; if (!zdr_array (zdrs, (char **)&objp->default_ace.default_ace_val, (u_int *) &objp->default_ace.default_ace_len, ~0, sizeof (nfsacl_ace), (zdrproc_t) zdr_nfsacl_ace)) return FALSE; return TRUE; } uint32_t zdr_GETACL3res (ZDR *zdrs, GETACL3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_GETACL3resok (zdrs, &objp->GETACL3res_u.resok)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_SETACL3args (ZDR *zdrs, SETACL3args *objp) { if (!zdr_nfs_fh3 (zdrs, &objp->dir)) return FALSE; if (!zdr_u_int (zdrs, &objp->mask)) return FALSE; if (!zdr_u_int (zdrs, &objp->ace_count)) return FALSE; if (!zdr_array (zdrs, (char **)&objp->ace.ace_val, (u_int *) &objp->ace.ace_len, ~0, sizeof (nfsacl_ace), (zdrproc_t) zdr_nfsacl_ace)) return FALSE; if (!zdr_u_int (zdrs, &objp->default_ace_count)) return FALSE; if (!zdr_array (zdrs, (char **)&objp->default_ace.default_ace_val, (u_int *) &objp->default_ace.default_ace_len, ~0, sizeof (nfsacl_ace), (zdrproc_t) zdr_nfsacl_ace)) return FALSE; return TRUE; } uint32_t zdr_SETACL3resok (ZDR *zdrs, SETACL3resok *objp) { if (!zdr_post_op_attr (zdrs, &objp->attr)) return FALSE; return TRUE; } uint32_t zdr_SETACL3res (ZDR *zdrs, SETACL3res *objp) { if (!zdr_nfsstat3 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NFS3_OK: if (!zdr_SETACL3resok (zdrs, &objp->SETACL3res_u.resok)) return FALSE; break; default: break; } return TRUE; } libnfs-libnfs-1.9.8/nfs/libnfs-raw-nfs.h000066400000000000000000001470621255745034100200700ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _NFS_H_RPCGEN #define _NFS_H_RPCGEN #include #include #ifdef __cplusplus extern "C" { #endif #define NFS3_FHSIZE 64 #define NFS3_WRITEVERFSIZE 8 #define NFS3_CREATEVERFSIZE 8 #define NFS3_COOKIEVERFSIZE 8 typedef char cookieverf3[NFS3_COOKIEVERFSIZE]; typedef uint64_t cookie3; struct nfs_fh3 { struct { u_int data_len; char *data_val; } data; }; typedef struct nfs_fh3 nfs_fh3; typedef char *filename3; struct diropargs3 { nfs_fh3 dir; filename3 name; }; typedef struct diropargs3 diropargs3; enum ftype3 { NF3REG = 1, NF3DIR = 2, NF3BLK = 3, NF3CHR = 4, NF3LNK = 5, NF3SOCK = 6, NF3FIFO = 7, }; typedef enum ftype3 ftype3; typedef u_int mode3; typedef u_int uid3; typedef u_int gid3; typedef uint64_t size3; typedef uint64_t fileid3; struct specdata3 { u_int specdata1; u_int specdata2; }; typedef struct specdata3 specdata3; struct nfstime3 { u_int seconds; u_int nseconds; }; typedef struct nfstime3 nfstime3; struct fattr3 { ftype3 type; mode3 mode; u_int nlink; uid3 uid; gid3 gid; size3 size; size3 used; specdata3 rdev; uint64_t fsid; fileid3 fileid; nfstime3 atime; nfstime3 mtime; nfstime3 ctime; }; typedef struct fattr3 fattr3; struct post_op_attr { uint32_t attributes_follow; union { fattr3 attributes; } post_op_attr_u; }; typedef struct post_op_attr post_op_attr; enum nfsstat3 { NFS3_OK = 0, NFS3ERR_PERM = 1, NFS3ERR_NOENT = 2, NFS3ERR_IO = 5, NFS3ERR_NXIO = 6, NFS3ERR_ACCES = 13, NFS3ERR_EXIST = 17, NFS3ERR_XDEV = 18, NFS3ERR_NODEV = 19, NFS3ERR_NOTDIR = 20, NFS3ERR_ISDIR = 21, NFS3ERR_INVAL = 22, NFS3ERR_FBIG = 27, NFS3ERR_NOSPC = 28, NFS3ERR_ROFS = 30, NFS3ERR_MLINK = 31, NFS3ERR_NAMETOOLONG = 63, NFS3ERR_NOTEMPTY = 66, NFS3ERR_DQUOT = 69, NFS3ERR_STALE = 70, NFS3ERR_REMOTE = 71, NFS3ERR_BADHANDLE = 10001, NFS3ERR_NOT_SYNC = 10002, NFS3ERR_BAD_COOKIE = 10003, NFS3ERR_NOTSUPP = 10004, NFS3ERR_TOOSMALL = 10005, NFS3ERR_SERVERFAULT = 10006, NFS3ERR_BADTYPE = 10007, NFS3ERR_JUKEBOX = 10008, }; typedef enum nfsstat3 nfsstat3; enum stable_how { UNSTABLE = 0, DATA_SYNC = 1, FILE_SYNC = 2, }; typedef enum stable_how stable_how; typedef uint64_t offset3; typedef u_int count3; struct wcc_attr { size3 size; nfstime3 mtime; nfstime3 ctime; }; typedef struct wcc_attr wcc_attr; struct pre_op_attr { uint32_t attributes_follow; union { wcc_attr attributes; } pre_op_attr_u; }; typedef struct pre_op_attr pre_op_attr; struct wcc_data { pre_op_attr before; post_op_attr after; }; typedef struct wcc_data wcc_data; struct WRITE3args { nfs_fh3 file; offset3 offset; count3 count; stable_how stable; struct { u_int data_len; char *data_val; } data; }; typedef struct WRITE3args WRITE3args; typedef char writeverf3[NFS3_WRITEVERFSIZE]; struct WRITE3resok { wcc_data file_wcc; count3 count; stable_how committed; writeverf3 verf; }; typedef struct WRITE3resok WRITE3resok; struct WRITE3resfail { wcc_data file_wcc; }; typedef struct WRITE3resfail WRITE3resfail; struct WRITE3res { nfsstat3 status; union { WRITE3resok resok; WRITE3resfail resfail; } WRITE3res_u; }; typedef struct WRITE3res WRITE3res; struct LOOKUP3args { diropargs3 what; }; typedef struct LOOKUP3args LOOKUP3args; struct LOOKUP3resok { nfs_fh3 object; post_op_attr obj_attributes; post_op_attr dir_attributes; }; typedef struct LOOKUP3resok LOOKUP3resok; struct LOOKUP3resfail { post_op_attr dir_attributes; }; typedef struct LOOKUP3resfail LOOKUP3resfail; struct LOOKUP3res { nfsstat3 status; union { LOOKUP3resok resok; LOOKUP3resfail resfail; } LOOKUP3res_u; }; typedef struct LOOKUP3res LOOKUP3res; struct COMMIT3args { nfs_fh3 file; offset3 offset; count3 count; }; typedef struct COMMIT3args COMMIT3args; struct COMMIT3resok { wcc_data file_wcc; writeverf3 verf; }; typedef struct COMMIT3resok COMMIT3resok; struct COMMIT3resfail { wcc_data file_wcc; }; typedef struct COMMIT3resfail COMMIT3resfail; struct COMMIT3res { nfsstat3 status; union { COMMIT3resok resok; COMMIT3resfail resfail; } COMMIT3res_u; }; typedef struct COMMIT3res COMMIT3res; #define ACCESS3_READ 0x0001 #define ACCESS3_LOOKUP 0x0002 #define ACCESS3_MODIFY 0x0004 #define ACCESS3_EXTEND 0x0008 #define ACCESS3_DELETE 0x0010 #define ACCESS3_EXECUTE 0x0020 struct ACCESS3args { nfs_fh3 object; u_int access; }; typedef struct ACCESS3args ACCESS3args; struct ACCESS3resok { post_op_attr obj_attributes; u_int access; }; typedef struct ACCESS3resok ACCESS3resok; struct ACCESS3resfail { post_op_attr obj_attributes; }; typedef struct ACCESS3resfail ACCESS3resfail; struct ACCESS3res { nfsstat3 status; union { ACCESS3resok resok; ACCESS3resfail resfail; } ACCESS3res_u; }; typedef struct ACCESS3res ACCESS3res; struct GETATTR3args { nfs_fh3 object; }; typedef struct GETATTR3args GETATTR3args; struct GETATTR3resok { fattr3 obj_attributes; }; typedef struct GETATTR3resok GETATTR3resok; struct GETATTR3res { nfsstat3 status; union { GETATTR3resok resok; } GETATTR3res_u; }; typedef struct GETATTR3res GETATTR3res; enum time_how { DONT_CHANGE = 0, SET_TO_SERVER_TIME = 1, SET_TO_CLIENT_TIME = 2, }; typedef enum time_how time_how; struct set_mode3 { uint32_t set_it; union { mode3 mode; } set_mode3_u; }; typedef struct set_mode3 set_mode3; struct set_uid3 { uint32_t set_it; union { uid3 uid; } set_uid3_u; }; typedef struct set_uid3 set_uid3; struct set_gid3 { uint32_t set_it; union { gid3 gid; } set_gid3_u; }; typedef struct set_gid3 set_gid3; struct set_size3 { uint32_t set_it; union { size3 size; } set_size3_u; }; typedef struct set_size3 set_size3; struct set_atime { time_how set_it; union { nfstime3 atime; } set_atime_u; }; typedef struct set_atime set_atime; struct set_mtime { time_how set_it; union { nfstime3 mtime; } set_mtime_u; }; typedef struct set_mtime set_mtime; struct sattr3 { set_mode3 mode; set_uid3 uid; set_gid3 gid; set_size3 size; set_atime atime; set_mtime mtime; }; typedef struct sattr3 sattr3; enum createmode3 { UNCHECKED = 0, GUARDED = 1, EXCLUSIVE = 2, }; typedef enum createmode3 createmode3; typedef char createverf3[NFS3_CREATEVERFSIZE]; struct createhow3 { createmode3 mode; union { sattr3 obj_attributes; sattr3 g_obj_attributes; createverf3 verf; } createhow3_u; }; typedef struct createhow3 createhow3; struct CREATE3args { diropargs3 where; createhow3 how; }; typedef struct CREATE3args CREATE3args; struct post_op_fh3 { uint32_t handle_follows; union { nfs_fh3 handle; } post_op_fh3_u; }; typedef struct post_op_fh3 post_op_fh3; struct CREATE3resok { post_op_fh3 obj; post_op_attr obj_attributes; wcc_data dir_wcc; }; typedef struct CREATE3resok CREATE3resok; struct CREATE3resfail { wcc_data dir_wcc; }; typedef struct CREATE3resfail CREATE3resfail; struct CREATE3res { nfsstat3 status; union { CREATE3resok resok; CREATE3resfail resfail; } CREATE3res_u; }; typedef struct CREATE3res CREATE3res; struct REMOVE3args { diropargs3 object; }; typedef struct REMOVE3args REMOVE3args; struct REMOVE3resok { wcc_data dir_wcc; }; typedef struct REMOVE3resok REMOVE3resok; struct REMOVE3resfail { wcc_data dir_wcc; }; typedef struct REMOVE3resfail REMOVE3resfail; struct REMOVE3res { nfsstat3 status; union { REMOVE3resok resok; REMOVE3resfail resfail; } REMOVE3res_u; }; typedef struct REMOVE3res REMOVE3res; struct READ3args { nfs_fh3 file; offset3 offset; count3 count; }; typedef struct READ3args READ3args; struct READ3resok { post_op_attr file_attributes; count3 count; uint32_t eof; struct { u_int data_len; char *data_val; } data; }; typedef struct READ3resok READ3resok; struct READ3resfail { post_op_attr file_attributes; }; typedef struct READ3resfail READ3resfail; struct READ3res { nfsstat3 status; union { READ3resok resok; READ3resfail resfail; } READ3res_u; }; typedef struct READ3res READ3res; #define FSF3_LINK 0x0001 #define FSF3_SYMLINK 0x0002 #define FSF3_HOMOGENEOUS 0x0008 #define FSF3_CANSETTIME 0x0010 struct FSINFO3args { nfs_fh3 fsroot; }; typedef struct FSINFO3args FSINFO3args; struct FSINFO3resok { post_op_attr obj_attributes; u_int rtmax; u_int rtpref; u_int rtmult; u_int wtmax; u_int wtpref; u_int wtmult; u_int dtpref; size3 maxfilesize; nfstime3 time_delta; u_int properties; }; typedef struct FSINFO3resok FSINFO3resok; struct FSINFO3resfail { post_op_attr obj_attributes; }; typedef struct FSINFO3resfail FSINFO3resfail; struct FSINFO3res { nfsstat3 status; union { FSINFO3resok resok; FSINFO3resfail resfail; } FSINFO3res_u; }; typedef struct FSINFO3res FSINFO3res; struct FSSTAT3args { nfs_fh3 fsroot; }; typedef struct FSSTAT3args FSSTAT3args; struct FSSTAT3resok { post_op_attr obj_attributes; size3 tbytes; size3 fbytes; size3 abytes; size3 tfiles; size3 ffiles; size3 afiles; u_int invarsec; }; typedef struct FSSTAT3resok FSSTAT3resok; struct FSSTAT3resfail { post_op_attr obj_attributes; }; typedef struct FSSTAT3resfail FSSTAT3resfail; struct FSSTAT3res { nfsstat3 status; union { FSSTAT3resok resok; FSSTAT3resfail resfail; } FSSTAT3res_u; }; typedef struct FSSTAT3res FSSTAT3res; struct PATHCONF3args { nfs_fh3 object; }; typedef struct PATHCONF3args PATHCONF3args; struct PATHCONF3resok { post_op_attr obj_attributes; u_int linkmax; u_int name_max; uint32_t no_trunc; uint32_t chown_restricted; uint32_t case_insensitive; uint32_t case_preserving; }; typedef struct PATHCONF3resok PATHCONF3resok; struct PATHCONF3resfail { post_op_attr obj_attributes; }; typedef struct PATHCONF3resfail PATHCONF3resfail; struct PATHCONF3res { nfsstat3 status; union { PATHCONF3resok resok; PATHCONF3resfail resfail; } PATHCONF3res_u; }; typedef struct PATHCONF3res PATHCONF3res; typedef char *nfspath3; struct symlinkdata3 { sattr3 symlink_attributes; nfspath3 symlink_data; }; typedef struct symlinkdata3 symlinkdata3; struct SYMLINK3args { diropargs3 where; symlinkdata3 symlink; }; typedef struct SYMLINK3args SYMLINK3args; struct SYMLINK3resok { post_op_fh3 obj; post_op_attr obj_attributes; wcc_data dir_wcc; }; typedef struct SYMLINK3resok SYMLINK3resok; struct SYMLINK3resfail { wcc_data dir_wcc; }; typedef struct SYMLINK3resfail SYMLINK3resfail; struct SYMLINK3res { nfsstat3 status; union { SYMLINK3resok resok; SYMLINK3resfail resfail; } SYMLINK3res_u; }; typedef struct SYMLINK3res SYMLINK3res; struct READLINK3args { nfs_fh3 symlink; }; typedef struct READLINK3args READLINK3args; struct READLINK3resok { post_op_attr symlink_attributes; nfspath3 data; }; typedef struct READLINK3resok READLINK3resok; struct READLINK3resfail { post_op_attr symlink_attributes; }; typedef struct READLINK3resfail READLINK3resfail; struct READLINK3res { nfsstat3 status; union { READLINK3resok resok; READLINK3resfail resfail; } READLINK3res_u; }; typedef struct READLINK3res READLINK3res; struct devicedata3 { sattr3 dev_attributes; specdata3 spec; }; typedef struct devicedata3 devicedata3; struct mknoddata3 { ftype3 type; union { devicedata3 chr_device; devicedata3 blk_device; sattr3 sock_attributes; sattr3 pipe_attributes; } mknoddata3_u; }; typedef struct mknoddata3 mknoddata3; struct MKNOD3args { diropargs3 where; mknoddata3 what; }; typedef struct MKNOD3args MKNOD3args; struct MKNOD3resok { post_op_fh3 obj; post_op_attr obj_attributes; wcc_data dir_wcc; }; typedef struct MKNOD3resok MKNOD3resok; struct MKNOD3resfail { wcc_data dir_wcc; }; typedef struct MKNOD3resfail MKNOD3resfail; struct MKNOD3res { nfsstat3 status; union { MKNOD3resok resok; MKNOD3resfail resfail; } MKNOD3res_u; }; typedef struct MKNOD3res MKNOD3res; struct MKDIR3args { diropargs3 where; sattr3 attributes; }; typedef struct MKDIR3args MKDIR3args; struct MKDIR3resok { post_op_fh3 obj; post_op_attr obj_attributes; wcc_data dir_wcc; }; typedef struct MKDIR3resok MKDIR3resok; struct MKDIR3resfail { wcc_data dir_wcc; }; typedef struct MKDIR3resfail MKDIR3resfail; struct MKDIR3res { nfsstat3 status; union { MKDIR3resok resok; MKDIR3resfail resfail; } MKDIR3res_u; }; typedef struct MKDIR3res MKDIR3res; struct RMDIR3args { diropargs3 object; }; typedef struct RMDIR3args RMDIR3args; struct RMDIR3resok { wcc_data dir_wcc; }; typedef struct RMDIR3resok RMDIR3resok; struct RMDIR3resfail { wcc_data dir_wcc; }; typedef struct RMDIR3resfail RMDIR3resfail; struct RMDIR3res { nfsstat3 status; union { RMDIR3resok resok; RMDIR3resfail resfail; } RMDIR3res_u; }; typedef struct RMDIR3res RMDIR3res; struct RENAME3args { diropargs3 from; diropargs3 to; }; typedef struct RENAME3args RENAME3args; struct RENAME3resok { wcc_data fromdir_wcc; wcc_data todir_wcc; }; typedef struct RENAME3resok RENAME3resok; struct RENAME3resfail { wcc_data fromdir_wcc; wcc_data todir_wcc; }; typedef struct RENAME3resfail RENAME3resfail; struct RENAME3res { nfsstat3 status; union { RENAME3resok resok; RENAME3resfail resfail; } RENAME3res_u; }; typedef struct RENAME3res RENAME3res; struct READDIRPLUS3args { nfs_fh3 dir; cookie3 cookie; cookieverf3 cookieverf; count3 dircount; count3 maxcount; }; typedef struct READDIRPLUS3args READDIRPLUS3args; struct entryplus3 { fileid3 fileid; filename3 name; cookie3 cookie; post_op_attr name_attributes; post_op_fh3 name_handle; struct entryplus3 *nextentry; }; typedef struct entryplus3 entryplus3; struct dirlistplus3 { entryplus3 *entries; uint32_t eof; }; typedef struct dirlistplus3 dirlistplus3; struct READDIRPLUS3resok { post_op_attr dir_attributes; cookieverf3 cookieverf; dirlistplus3 reply; }; typedef struct READDIRPLUS3resok READDIRPLUS3resok; struct READDIRPLUS3resfail { post_op_attr dir_attributes; }; typedef struct READDIRPLUS3resfail READDIRPLUS3resfail; struct READDIRPLUS3res { nfsstat3 status; union { READDIRPLUS3resok resok; READDIRPLUS3resfail resfail; } READDIRPLUS3res_u; }; typedef struct READDIRPLUS3res READDIRPLUS3res; struct READDIR3args { nfs_fh3 dir; cookie3 cookie; cookieverf3 cookieverf; count3 count; }; typedef struct READDIR3args READDIR3args; struct entry3 { fileid3 fileid; filename3 name; cookie3 cookie; struct entry3 *nextentry; }; typedef struct entry3 entry3; struct dirlist3 { entry3 *entries; uint32_t eof; }; typedef struct dirlist3 dirlist3; struct READDIR3resok { post_op_attr dir_attributes; cookieverf3 cookieverf; dirlist3 reply; }; typedef struct READDIR3resok READDIR3resok; struct READDIR3resfail { post_op_attr dir_attributes; }; typedef struct READDIR3resfail READDIR3resfail; struct READDIR3res { nfsstat3 status; union { READDIR3resok resok; READDIR3resfail resfail; } READDIR3res_u; }; typedef struct READDIR3res READDIR3res; struct LINK3args { nfs_fh3 file; diropargs3 link; }; typedef struct LINK3args LINK3args; struct LINK3resok { post_op_attr file_attributes; wcc_data linkdir_wcc; }; typedef struct LINK3resok LINK3resok; struct LINK3resfail { post_op_attr file_attributes; wcc_data linkdir_wcc; }; typedef struct LINK3resfail LINK3resfail; struct LINK3res { nfsstat3 status; union { LINK3resok resok; LINK3resfail resfail; } LINK3res_u; }; typedef struct LINK3res LINK3res; struct sattrguard3 { uint32_t check; union { nfstime3 obj_ctime; } sattrguard3_u; }; typedef struct sattrguard3 sattrguard3; struct SETATTR3args { nfs_fh3 object; sattr3 new_attributes; sattrguard3 guard; }; typedef struct SETATTR3args SETATTR3args; struct SETATTR3resok { wcc_data obj_wcc; }; typedef struct SETATTR3resok SETATTR3resok; struct SETATTR3resfail { wcc_data obj_wcc; }; typedef struct SETATTR3resfail SETATTR3resfail; struct SETATTR3res { nfsstat3 status; union { SETATTR3resok resok; SETATTR3resfail resfail; } SETATTR3res_u; }; typedef struct SETATTR3res SETATTR3res; #define FHSIZE2 32 typedef char fhandle2[FHSIZE2]; enum ftype2 { NF2NON = 0, NF2REG = 1, NF2DIR = 2, NF2BLK = 3, NF2CHR = 4, NF2LNK = 5, }; typedef enum ftype2 ftype2; struct fattr2 { ftype2 type; u_int mode; u_int nlink; u_int uid; u_int gid; u_int size; u_int blocksize; u_int rdev; u_int blocks; u_int fsid; u_int fileid; nfstime3 atime; nfstime3 mtime; nfstime3 ctime; }; typedef struct fattr2 fattr2; struct sattr2 { u_int mode; u_int uid; u_int gid; u_int size; nfstime3 atime; nfstime3 mtime; }; typedef struct sattr2 sattr2; #define MAXNAMLEN2 255 typedef char *filename2; #define MAXPATHLEN2 1024 typedef char *path2; #define NFSMAXDATA2 8192 typedef struct { u_int nfsdata2_len; char *nfsdata2_val; } nfsdata2; #define NFSCOOKIESIZE2 4 typedef char nfscookie2[NFSCOOKIESIZE2]; struct entry2 { u_int fileid; filename2 name; nfscookie2 cookie; struct entry2 *nextentry; }; typedef struct entry2 entry2; struct diropargs2 { fhandle2 dir; filename2 name; }; typedef struct diropargs2 diropargs2; struct GETATTR2args { fhandle2 fhandle; }; typedef struct GETATTR2args GETATTR2args; struct GETATTR2resok { fattr2 attributes; }; typedef struct GETATTR2resok GETATTR2resok; struct GETATTR2res { nfsstat3 status; union { GETATTR2resok resok; } GETATTR2res_u; }; typedef struct GETATTR2res GETATTR2res; struct SETATTR2args { fhandle2 fhandle; sattr2 attributes; }; typedef struct SETATTR2args SETATTR2args; struct SETATTR2resok { fattr2 attributes; }; typedef struct SETATTR2resok SETATTR2resok; struct SETATTR2res { nfsstat3 status; union { SETATTR2resok resok; } SETATTR2res_u; }; typedef struct SETATTR2res SETATTR2res; struct LOOKUP2args { diropargs2 what; }; typedef struct LOOKUP2args LOOKUP2args; struct LOOKUP2resok { fhandle2 file; fattr2 attributes; }; typedef struct LOOKUP2resok LOOKUP2resok; struct LOOKUP2res { nfsstat3 status; union { LOOKUP2resok resok; } LOOKUP2res_u; }; typedef struct LOOKUP2res LOOKUP2res; struct READLINK2args { fhandle2 file; }; typedef struct READLINK2args READLINK2args; struct READLINK2resok { path2 data; }; typedef struct READLINK2resok READLINK2resok; struct READLINK2res { nfsstat3 status; union { READLINK2resok resok; } READLINK2res_u; }; typedef struct READLINK2res READLINK2res; struct READ2args { fhandle2 file; u_int offset; u_int count; u_int totalcount; }; typedef struct READ2args READ2args; struct READ2resok { fattr2 attributes; nfsdata2 data; }; typedef struct READ2resok READ2resok; struct READ2res { nfsstat3 status; union { READ2resok resok; } READ2res_u; }; typedef struct READ2res READ2res; struct WRITE2args { fhandle2 file; u_int beginoffset; u_int offset; u_int totalcount; nfsdata2 data; }; typedef struct WRITE2args WRITE2args; struct WRITE2resok { fattr2 attributes; }; typedef struct WRITE2resok WRITE2resok; struct WRITE2res { nfsstat3 status; union { WRITE2resok resok; } WRITE2res_u; }; typedef struct WRITE2res WRITE2res; struct CREATE2args { diropargs2 where; sattr2 attributes; }; typedef struct CREATE2args CREATE2args; struct CREATE2resok { fhandle2 file; fattr2 attributes; }; typedef struct CREATE2resok CREATE2resok; struct CREATE2res { nfsstat3 status; union { CREATE2resok resok; } CREATE2res_u; }; typedef struct CREATE2res CREATE2res; struct REMOVE2args { diropargs2 what; }; typedef struct REMOVE2args REMOVE2args; struct REMOVE2res { nfsstat3 status; }; typedef struct REMOVE2res REMOVE2res; struct RENAME2args { diropargs2 from; diropargs2 to; }; typedef struct RENAME2args RENAME2args; struct RENAME2res { nfsstat3 status; }; typedef struct RENAME2res RENAME2res; struct LINK2args { fhandle2 from; diropargs2 to; }; typedef struct LINK2args LINK2args; struct LINK2res { nfsstat3 status; }; typedef struct LINK2res LINK2res; struct SYMLINK2args { diropargs2 from; path2 to; sattr2 attributes; }; typedef struct SYMLINK2args SYMLINK2args; struct SYMLINK2res { nfsstat3 status; }; typedef struct SYMLINK2res SYMLINK2res; struct MKDIR2args { diropargs2 where; sattr2 attributes; }; typedef struct MKDIR2args MKDIR2args; struct MKDIR2resok { fhandle2 file; fattr2 attributes; }; typedef struct MKDIR2resok MKDIR2resok; struct MKDIR2res { nfsstat3 status; union { MKDIR2resok resok; } MKDIR2res_u; }; typedef struct MKDIR2res MKDIR2res; struct RMDIR2args { diropargs2 what; }; typedef struct RMDIR2args RMDIR2args; struct RMDIR2res { nfsstat3 status; }; typedef struct RMDIR2res RMDIR2res; struct READDIR2args { fhandle2 dir; nfscookie2 cookie; u_int count; }; typedef struct READDIR2args READDIR2args; struct READDIR2resok { entry2 *entries; uint32_t eof; }; typedef struct READDIR2resok READDIR2resok; struct READDIR2res { nfsstat3 status; union { READDIR2resok resok; } READDIR2res_u; }; typedef struct READDIR2res READDIR2res; struct STATFS2args { fhandle2 dir; }; typedef struct STATFS2args STATFS2args; struct STATFS2resok { u_int tsize; u_int bsize; u_int blocks; u_int bfree; u_int bavail; }; typedef struct STATFS2resok STATFS2resok; struct STATFS2res { nfsstat3 status; union { STATFS2resok resok; } STATFS2res_u; }; typedef struct STATFS2res STATFS2res; enum nfsacl_type { NFSACL_TYPE_USER_OBJ = 0x0001, NFSACL_TYPE_USER = 0x0002, NFSACL_TYPE_GROUP_OBJ = 0x0004, NFSACL_TYPE_GROUP = 0x0008, NFSACL_TYPE_CLASS_OBJ = 0x0010, NFSACL_TYPE_CLASS = 0x0020, NFSACL_TYPE_DEFAULT = 0x1000, NFSACL_TYPE_DEFAULT_USER_OBJ = 0x1001, NFSACL_TYPE_DEFAULT_USER = 0x1002, NFSACL_TYPE_DEFAULT_GROUP_OBJ = 0x1004, NFSACL_TYPE_DEFAULT_GROUP = 0x1008, NFSACL_TYPE_DEFAULT_CLASS_OBJ = 0x1010, NFSACL_TYPE_DEFAULT_OTHER_OBJ = 0x1020, }; typedef enum nfsacl_type nfsacl_type; #define NFSACL_PERM_READ 0x04 #define NFSACL_PERM_WRITE 0x02 #define NFSACL_PERM_EXEC 0x01 struct nfsacl_ace { enum nfsacl_type type; u_int id; u_int perm; }; typedef struct nfsacl_ace nfsacl_ace; #define NFSACL_MASK_ACL_ENTRY 0x0001 #define NFSACL_MASK_ACL_COUNT 0x0002 #define NFSACL_MASK_ACL_DEFAULT_ENTRY 0x0004 #define NFSACL_MASK_ACL_DEFAULT_COUNT 0x0008 struct GETACL3args { nfs_fh3 dir; u_int mask; }; typedef struct GETACL3args GETACL3args; struct GETACL3resok { post_op_attr attr; u_int mask; u_int ace_count; struct { u_int ace_len; struct nfsacl_ace *ace_val; } ace; u_int default_ace_count; struct { u_int default_ace_len; struct nfsacl_ace *default_ace_val; } default_ace; }; typedef struct GETACL3resok GETACL3resok; struct GETACL3res { nfsstat3 status; union { GETACL3resok resok; } GETACL3res_u; }; typedef struct GETACL3res GETACL3res; struct SETACL3args { nfs_fh3 dir; u_int mask; u_int ace_count; struct { u_int ace_len; struct nfsacl_ace *ace_val; } ace; u_int default_ace_count; struct { u_int default_ace_len; struct nfsacl_ace *default_ace_val; } default_ace; }; typedef struct SETACL3args SETACL3args; struct SETACL3resok { post_op_attr attr; }; typedef struct SETACL3resok SETACL3resok; struct SETACL3res { nfsstat3 status; union { SETACL3resok resok; } SETACL3res_u; }; typedef struct SETACL3res SETACL3res; #define NFS_PROGRAM 100003 #define NFS_V2 2 #if defined(__STDC__) || defined(__cplusplus) #define NFS2_NULL 0 extern void * nfs2_null_2(void *, void *); extern void * nfs2_null_2_svc(void *, struct svc_req *); #define NFS2_GETATTR 1 extern GETATTR2res * nfs2_getattr_2(GETATTR2args *, void *); extern GETATTR2res * nfs2_getattr_2_svc(GETATTR2args *, struct svc_req *); #define NFS2_SETATTR 2 extern SETATTR2res * nfs2_setattr_2(SETATTR2args *, void *); extern SETATTR2res * nfs2_setattr_2_svc(SETATTR2args *, struct svc_req *); #define NFS2_LOOKUP 4 extern LOOKUP2res * nfs2_lookup_2(LOOKUP2args *, void *); extern LOOKUP2res * nfs2_lookup_2_svc(LOOKUP2args *, struct svc_req *); #define NFS2_READLINK 5 extern READLINK2res * nfs2_readlink_2(READLINK2args *, void *); extern READLINK2res * nfs2_readlink_2_svc(READLINK2args *, struct svc_req *); #define NFS2_READ 6 extern READ2res * nfs2_read_2(READ2args *, void *); extern READ2res * nfs2_read_2_svc(READ2args *, struct svc_req *); #define NFS2_WRITE 8 extern WRITE2res * nfs2_write_2(WRITE2args *, void *); extern WRITE2res * nfs2_write_2_svc(WRITE2args *, struct svc_req *); #define NFS2_CREATE 9 extern CREATE2res * nfs2_create_2(CREATE2args *, void *); extern CREATE2res * nfs2_create_2_svc(CREATE2args *, struct svc_req *); #define NFS2_REMOVE 10 extern REMOVE2res * nfs2_remove_2(REMOVE2args *, void *); extern REMOVE2res * nfs2_remove_2_svc(REMOVE2args *, struct svc_req *); #define NFS2_RENAME 11 extern RENAME2res * nfs2_rename_2(RENAME2args *, void *); extern RENAME2res * nfs2_rename_2_svc(RENAME2args *, struct svc_req *); #define NFS2_LINK 12 extern LINK2res * nfs2_link_2(LINK2args *, void *); extern LINK2res * nfs2_link_2_svc(LINK2args *, struct svc_req *); #define NFS2_SYMLINK 13 extern SYMLINK2res * nfs2_symlink_2(SYMLINK2args *, void *); extern SYMLINK2res * nfs2_symlink_2_svc(SYMLINK2args *, struct svc_req *); #define NFS2_MKDIR 14 extern MKDIR2res * nfs2_mkdir_2(MKDIR2args *, void *); extern MKDIR2res * nfs2_mkdir_2_svc(MKDIR2args *, struct svc_req *); #define NFS2_RMDIR 15 extern RMDIR2res * nfs2_rmdir_2(RMDIR2args *, void *); extern RMDIR2res * nfs2_rmdir_2_svc(RMDIR2args *, struct svc_req *); #define NFS2_READDIR 16 extern READDIR2res * nfs2_readdir_2(READDIR2args *, void *); extern READDIR2res * nfs2_readdir_2_svc(READDIR2args *, struct svc_req *); #define NFS2_STATFS 17 extern STATFS2res * nfs2_statfs_2(STATFS2args *, void *); extern STATFS2res * nfs2_statfs_2_svc(STATFS2args *, struct svc_req *); extern int nfs_program_2_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define NFS2_NULL 0 extern void * nfs2_null_2(); extern void * nfs2_null_2_svc(); #define NFS2_GETATTR 1 extern GETATTR2res * nfs2_getattr_2(); extern GETATTR2res * nfs2_getattr_2_svc(); #define NFS2_SETATTR 2 extern SETATTR2res * nfs2_setattr_2(); extern SETATTR2res * nfs2_setattr_2_svc(); #define NFS2_LOOKUP 4 extern LOOKUP2res * nfs2_lookup_2(); extern LOOKUP2res * nfs2_lookup_2_svc(); #define NFS2_READLINK 5 extern READLINK2res * nfs2_readlink_2(); extern READLINK2res * nfs2_readlink_2_svc(); #define NFS2_READ 6 extern READ2res * nfs2_read_2(); extern READ2res * nfs2_read_2_svc(); #define NFS2_WRITE 8 extern WRITE2res * nfs2_write_2(); extern WRITE2res * nfs2_write_2_svc(); #define NFS2_CREATE 9 extern CREATE2res * nfs2_create_2(); extern CREATE2res * nfs2_create_2_svc(); #define NFS2_REMOVE 10 extern REMOVE2res * nfs2_remove_2(); extern REMOVE2res * nfs2_remove_2_svc(); #define NFS2_RENAME 11 extern RENAME2res * nfs2_rename_2(); extern RENAME2res * nfs2_rename_2_svc(); #define NFS2_LINK 12 extern LINK2res * nfs2_link_2(); extern LINK2res * nfs2_link_2_svc(); #define NFS2_SYMLINK 13 extern SYMLINK2res * nfs2_symlink_2(); extern SYMLINK2res * nfs2_symlink_2_svc(); #define NFS2_MKDIR 14 extern MKDIR2res * nfs2_mkdir_2(); extern MKDIR2res * nfs2_mkdir_2_svc(); #define NFS2_RMDIR 15 extern RMDIR2res * nfs2_rmdir_2(); extern RMDIR2res * nfs2_rmdir_2_svc(); #define NFS2_READDIR 16 extern READDIR2res * nfs2_readdir_2(); extern READDIR2res * nfs2_readdir_2_svc(); #define NFS2_STATFS 17 extern STATFS2res * nfs2_statfs_2(); extern STATFS2res * nfs2_statfs_2_svc(); extern int nfs_program_2_freeresult (); #endif /* K&R C */ #define NFS_V3 3 #if defined(__STDC__) || defined(__cplusplus) #define NFS3_NULL 0 extern void * nfs3_null_3(void *, void *); extern void * nfs3_null_3_svc(void *, struct svc_req *); #define NFS3_GETATTR 1 extern GETATTR3res * nfs3_getattr_3(GETATTR3args *, void *); extern GETATTR3res * nfs3_getattr_3_svc(GETATTR3args *, struct svc_req *); #define NFS3_SETATTR 2 extern SETATTR3res * nfs3_setattr_3(SETATTR3args *, void *); extern SETATTR3res * nfs3_setattr_3_svc(SETATTR3args *, struct svc_req *); #define NFS3_LOOKUP 3 extern LOOKUP3res * nfs3_lookup_3(LOOKUP3args *, void *); extern LOOKUP3res * nfs3_lookup_3_svc(LOOKUP3args *, struct svc_req *); #define NFS3_ACCESS 4 extern ACCESS3res * nfs3_access_3(ACCESS3args *, void *); extern ACCESS3res * nfs3_access_3_svc(ACCESS3args *, struct svc_req *); #define NFS3_READLINK 5 extern READLINK3res * nfs3_readlink_3(READLINK3args *, void *); extern READLINK3res * nfs3_readlink_3_svc(READLINK3args *, struct svc_req *); #define NFS3_READ 6 extern READ3res * nfs3_read_3(READ3args *, void *); extern READ3res * nfs3_read_3_svc(READ3args *, struct svc_req *); #define NFS3_WRITE 7 extern WRITE3res * nfs3_write_3(WRITE3args *, void *); extern WRITE3res * nfs3_write_3_svc(WRITE3args *, struct svc_req *); #define NFS3_CREATE 8 extern CREATE3res * nfs3_create_3(CREATE3args *, void *); extern CREATE3res * nfs3_create_3_svc(CREATE3args *, struct svc_req *); #define NFS3_MKDIR 9 extern MKDIR3res * nfs3_mkdir_3(MKDIR3args *, void *); extern MKDIR3res * nfs3_mkdir_3_svc(MKDIR3args *, struct svc_req *); #define NFS3_SYMLINK 10 extern SYMLINK3res * nfs3_symlink_3(SYMLINK3args *, void *); extern SYMLINK3res * nfs3_symlink_3_svc(SYMLINK3args *, struct svc_req *); #define NFS3_MKNOD 11 extern MKNOD3res * nfs3_mknod_3(MKNOD3args *, void *); extern MKNOD3res * nfs3_mknod_3_svc(MKNOD3args *, struct svc_req *); #define NFS3_REMOVE 12 extern REMOVE3res * nfs3_remove_3(REMOVE3args *, void *); extern REMOVE3res * nfs3_remove_3_svc(REMOVE3args *, struct svc_req *); #define NFS3_RMDIR 13 extern RMDIR3res * nfs3_rmdir_3(RMDIR3args *, void *); extern RMDIR3res * nfs3_rmdir_3_svc(RMDIR3args *, struct svc_req *); #define NFS3_RENAME 14 extern RENAME3res * nfs3_rename_3(RENAME3args *, void *); extern RENAME3res * nfs3_rename_3_svc(RENAME3args *, struct svc_req *); #define NFS3_LINK 15 extern LINK3res * nfs3_link_3(LINK3args *, void *); extern LINK3res * nfs3_link_3_svc(LINK3args *, struct svc_req *); #define NFS3_READDIR 16 extern READDIR3res * nfs3_readdir_3(READDIR3args *, void *); extern READDIR3res * nfs3_readdir_3_svc(READDIR3args *, struct svc_req *); #define NFS3_READDIRPLUS 17 extern READDIRPLUS3res * nfs3_readdirplus_3(READDIRPLUS3args *, void *); extern READDIRPLUS3res * nfs3_readdirplus_3_svc(READDIRPLUS3args *, struct svc_req *); #define NFS3_FSSTAT 18 extern FSSTAT3res * nfs3_fsstat_3(FSSTAT3args *, void *); extern FSSTAT3res * nfs3_fsstat_3_svc(FSSTAT3args *, struct svc_req *); #define NFS3_FSINFO 19 extern FSINFO3res * nfs3_fsinfo_3(FSINFO3args *, void *); extern FSINFO3res * nfs3_fsinfo_3_svc(FSINFO3args *, struct svc_req *); #define NFS3_PATHCONF 20 extern PATHCONF3res * nfs3_pathconf_3(PATHCONF3args *, void *); extern PATHCONF3res * nfs3_pathconf_3_svc(PATHCONF3args *, struct svc_req *); #define NFS3_COMMIT 21 extern COMMIT3res * nfs3_commit_3(COMMIT3args *, void *); extern COMMIT3res * nfs3_commit_3_svc(COMMIT3args *, struct svc_req *); extern int nfs_program_3_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define NFS3_NULL 0 extern void * nfs3_null_3(); extern void * nfs3_null_3_svc(); #define NFS3_GETATTR 1 extern GETATTR3res * nfs3_getattr_3(); extern GETATTR3res * nfs3_getattr_3_svc(); #define NFS3_SETATTR 2 extern SETATTR3res * nfs3_setattr_3(); extern SETATTR3res * nfs3_setattr_3_svc(); #define NFS3_LOOKUP 3 extern LOOKUP3res * nfs3_lookup_3(); extern LOOKUP3res * nfs3_lookup_3_svc(); #define NFS3_ACCESS 4 extern ACCESS3res * nfs3_access_3(); extern ACCESS3res * nfs3_access_3_svc(); #define NFS3_READLINK 5 extern READLINK3res * nfs3_readlink_3(); extern READLINK3res * nfs3_readlink_3_svc(); #define NFS3_READ 6 extern READ3res * nfs3_read_3(); extern READ3res * nfs3_read_3_svc(); #define NFS3_WRITE 7 extern WRITE3res * nfs3_write_3(); extern WRITE3res * nfs3_write_3_svc(); #define NFS3_CREATE 8 extern CREATE3res * nfs3_create_3(); extern CREATE3res * nfs3_create_3_svc(); #define NFS3_MKDIR 9 extern MKDIR3res * nfs3_mkdir_3(); extern MKDIR3res * nfs3_mkdir_3_svc(); #define NFS3_SYMLINK 10 extern SYMLINK3res * nfs3_symlink_3(); extern SYMLINK3res * nfs3_symlink_3_svc(); #define NFS3_MKNOD 11 extern MKNOD3res * nfs3_mknod_3(); extern MKNOD3res * nfs3_mknod_3_svc(); #define NFS3_REMOVE 12 extern REMOVE3res * nfs3_remove_3(); extern REMOVE3res * nfs3_remove_3_svc(); #define NFS3_RMDIR 13 extern RMDIR3res * nfs3_rmdir_3(); extern RMDIR3res * nfs3_rmdir_3_svc(); #define NFS3_RENAME 14 extern RENAME3res * nfs3_rename_3(); extern RENAME3res * nfs3_rename_3_svc(); #define NFS3_LINK 15 extern LINK3res * nfs3_link_3(); extern LINK3res * nfs3_link_3_svc(); #define NFS3_READDIR 16 extern READDIR3res * nfs3_readdir_3(); extern READDIR3res * nfs3_readdir_3_svc(); #define NFS3_READDIRPLUS 17 extern READDIRPLUS3res * nfs3_readdirplus_3(); extern READDIRPLUS3res * nfs3_readdirplus_3_svc(); #define NFS3_FSSTAT 18 extern FSSTAT3res * nfs3_fsstat_3(); extern FSSTAT3res * nfs3_fsstat_3_svc(); #define NFS3_FSINFO 19 extern FSINFO3res * nfs3_fsinfo_3(); extern FSINFO3res * nfs3_fsinfo_3_svc(); #define NFS3_PATHCONF 20 extern PATHCONF3res * nfs3_pathconf_3(); extern PATHCONF3res * nfs3_pathconf_3_svc(); #define NFS3_COMMIT 21 extern COMMIT3res * nfs3_commit_3(); extern COMMIT3res * nfs3_commit_3_svc(); extern int nfs_program_3_freeresult (); #endif /* K&R C */ #define NFSACL_PROGRAM 100227 #define NFSACL_V3 3 #if defined(__STDC__) || defined(__cplusplus) #define NFSACL3_NULL 0 extern void * nfsacl3_null_3(void *, void *); extern void * nfsacl3_null_3_svc(void *, struct svc_req *); #define NFSACL3_GETACL 1 extern GETACL3res * nfsacl3_getacl_3(GETACL3args *, void *); extern GETACL3res * nfsacl3_getacl_3_svc(GETACL3args *, struct svc_req *); #define NFSACL3_SETACL 2 extern SETACL3res * nfsacl3_setacl_3(SETACL3args *, void *); extern SETACL3res * nfsacl3_setacl_3_svc(SETACL3args *, struct svc_req *); extern int nfsacl_program_3_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define NFSACL3_NULL 0 extern void * nfsacl3_null_3(); extern void * nfsacl3_null_3_svc(); #define NFSACL3_GETACL 1 extern GETACL3res * nfsacl3_getacl_3(); extern GETACL3res * nfsacl3_getacl_3_svc(); #define NFSACL3_SETACL 2 extern SETACL3res * nfsacl3_setacl_3(); extern SETACL3res * nfsacl3_setacl_3_svc(); extern int nfsacl_program_3_freeresult (); #endif /* K&R C */ /* the zdr functions */ #if defined(__STDC__) || defined(__cplusplus) extern uint32_t zdr_cookieverf3 (ZDR *, cookieverf3); extern uint32_t zdr_cookie3 (ZDR *, cookie3*); extern uint32_t zdr_nfs_fh3 (ZDR *, nfs_fh3*); extern uint32_t zdr_filename3 (ZDR *, filename3*); extern uint32_t zdr_diropargs3 (ZDR *, diropargs3*); extern uint32_t zdr_ftype3 (ZDR *, ftype3*); extern uint32_t zdr_mode3 (ZDR *, mode3*); extern uint32_t zdr_uid3 (ZDR *, uid3*); extern uint32_t zdr_gid3 (ZDR *, gid3*); extern uint32_t zdr_size3 (ZDR *, size3*); extern uint32_t zdr_fileid3 (ZDR *, fileid3*); extern uint32_t zdr_specdata3 (ZDR *, specdata3*); extern uint32_t zdr_nfstime3 (ZDR *, nfstime3*); extern uint32_t zdr_fattr3 (ZDR *, fattr3*); extern uint32_t zdr_post_op_attr (ZDR *, post_op_attr*); extern uint32_t zdr_nfsstat3 (ZDR *, nfsstat3*); extern uint32_t zdr_stable_how (ZDR *, stable_how*); extern uint32_t zdr_offset3 (ZDR *, offset3*); extern uint32_t zdr_count3 (ZDR *, count3*); extern uint32_t zdr_wcc_attr (ZDR *, wcc_attr*); extern uint32_t zdr_pre_op_attr (ZDR *, pre_op_attr*); extern uint32_t zdr_wcc_data (ZDR *, wcc_data*); extern uint32_t zdr_WRITE3args (ZDR *, WRITE3args*); extern uint32_t zdr_writeverf3 (ZDR *, writeverf3); extern uint32_t zdr_WRITE3resok (ZDR *, WRITE3resok*); extern uint32_t zdr_WRITE3resfail (ZDR *, WRITE3resfail*); extern uint32_t zdr_WRITE3res (ZDR *, WRITE3res*); extern uint32_t zdr_LOOKUP3args (ZDR *, LOOKUP3args*); extern uint32_t zdr_LOOKUP3resok (ZDR *, LOOKUP3resok*); extern uint32_t zdr_LOOKUP3resfail (ZDR *, LOOKUP3resfail*); extern uint32_t zdr_LOOKUP3res (ZDR *, LOOKUP3res*); extern uint32_t zdr_COMMIT3args (ZDR *, COMMIT3args*); extern uint32_t zdr_COMMIT3resok (ZDR *, COMMIT3resok*); extern uint32_t zdr_COMMIT3resfail (ZDR *, COMMIT3resfail*); extern uint32_t zdr_COMMIT3res (ZDR *, COMMIT3res*); extern uint32_t zdr_ACCESS3args (ZDR *, ACCESS3args*); extern uint32_t zdr_ACCESS3resok (ZDR *, ACCESS3resok*); extern uint32_t zdr_ACCESS3resfail (ZDR *, ACCESS3resfail*); extern uint32_t zdr_ACCESS3res (ZDR *, ACCESS3res*); extern uint32_t zdr_GETATTR3args (ZDR *, GETATTR3args*); extern uint32_t zdr_GETATTR3resok (ZDR *, GETATTR3resok*); extern uint32_t zdr_GETATTR3res (ZDR *, GETATTR3res*); extern uint32_t zdr_time_how (ZDR *, time_how*); extern uint32_t zdr_set_mode3 (ZDR *, set_mode3*); extern uint32_t zdr_set_uid3 (ZDR *, set_uid3*); extern uint32_t zdr_set_gid3 (ZDR *, set_gid3*); extern uint32_t zdr_set_size3 (ZDR *, set_size3*); extern uint32_t zdr_set_atime (ZDR *, set_atime*); extern uint32_t zdr_set_mtime (ZDR *, set_mtime*); extern uint32_t zdr_sattr3 (ZDR *, sattr3*); extern uint32_t zdr_createmode3 (ZDR *, createmode3*); extern uint32_t zdr_createverf3 (ZDR *, createverf3); extern uint32_t zdr_createhow3 (ZDR *, createhow3*); extern uint32_t zdr_CREATE3args (ZDR *, CREATE3args*); extern uint32_t zdr_post_op_fh3 (ZDR *, post_op_fh3*); extern uint32_t zdr_CREATE3resok (ZDR *, CREATE3resok*); extern uint32_t zdr_CREATE3resfail (ZDR *, CREATE3resfail*); extern uint32_t zdr_CREATE3res (ZDR *, CREATE3res*); extern uint32_t zdr_REMOVE3args (ZDR *, REMOVE3args*); extern uint32_t zdr_REMOVE3resok (ZDR *, REMOVE3resok*); extern uint32_t zdr_REMOVE3resfail (ZDR *, REMOVE3resfail*); extern uint32_t zdr_REMOVE3res (ZDR *, REMOVE3res*); extern uint32_t zdr_READ3args (ZDR *, READ3args*); extern uint32_t zdr_READ3resok (ZDR *, READ3resok*); extern uint32_t zdr_READ3resfail (ZDR *, READ3resfail*); extern uint32_t zdr_READ3res (ZDR *, READ3res*); extern uint32_t zdr_FSINFO3args (ZDR *, FSINFO3args*); extern uint32_t zdr_FSINFO3resok (ZDR *, FSINFO3resok*); extern uint32_t zdr_FSINFO3resfail (ZDR *, FSINFO3resfail*); extern uint32_t zdr_FSINFO3res (ZDR *, FSINFO3res*); extern uint32_t zdr_FSSTAT3args (ZDR *, FSSTAT3args*); extern uint32_t zdr_FSSTAT3resok (ZDR *, FSSTAT3resok*); extern uint32_t zdr_FSSTAT3resfail (ZDR *, FSSTAT3resfail*); extern uint32_t zdr_FSSTAT3res (ZDR *, FSSTAT3res*); extern uint32_t zdr_PATHCONF3args (ZDR *, PATHCONF3args*); extern uint32_t zdr_PATHCONF3resok (ZDR *, PATHCONF3resok*); extern uint32_t zdr_PATHCONF3resfail (ZDR *, PATHCONF3resfail*); extern uint32_t zdr_PATHCONF3res (ZDR *, PATHCONF3res*); extern uint32_t zdr_nfspath3 (ZDR *, nfspath3*); extern uint32_t zdr_symlinkdata3 (ZDR *, symlinkdata3*); extern uint32_t zdr_SYMLINK3args (ZDR *, SYMLINK3args*); extern uint32_t zdr_SYMLINK3resok (ZDR *, SYMLINK3resok*); extern uint32_t zdr_SYMLINK3resfail (ZDR *, SYMLINK3resfail*); extern uint32_t zdr_SYMLINK3res (ZDR *, SYMLINK3res*); extern uint32_t zdr_READLINK3args (ZDR *, READLINK3args*); extern uint32_t zdr_READLINK3resok (ZDR *, READLINK3resok*); extern uint32_t zdr_READLINK3resfail (ZDR *, READLINK3resfail*); extern uint32_t zdr_READLINK3res (ZDR *, READLINK3res*); extern uint32_t zdr_devicedata3 (ZDR *, devicedata3*); extern uint32_t zdr_mknoddata3 (ZDR *, mknoddata3*); extern uint32_t zdr_MKNOD3args (ZDR *, MKNOD3args*); extern uint32_t zdr_MKNOD3resok (ZDR *, MKNOD3resok*); extern uint32_t zdr_MKNOD3resfail (ZDR *, MKNOD3resfail*); extern uint32_t zdr_MKNOD3res (ZDR *, MKNOD3res*); extern uint32_t zdr_MKDIR3args (ZDR *, MKDIR3args*); extern uint32_t zdr_MKDIR3resok (ZDR *, MKDIR3resok*); extern uint32_t zdr_MKDIR3resfail (ZDR *, MKDIR3resfail*); extern uint32_t zdr_MKDIR3res (ZDR *, MKDIR3res*); extern uint32_t zdr_RMDIR3args (ZDR *, RMDIR3args*); extern uint32_t zdr_RMDIR3resok (ZDR *, RMDIR3resok*); extern uint32_t zdr_RMDIR3resfail (ZDR *, RMDIR3resfail*); extern uint32_t zdr_RMDIR3res (ZDR *, RMDIR3res*); extern uint32_t zdr_RENAME3args (ZDR *, RENAME3args*); extern uint32_t zdr_RENAME3resok (ZDR *, RENAME3resok*); extern uint32_t zdr_RENAME3resfail (ZDR *, RENAME3resfail*); extern uint32_t zdr_RENAME3res (ZDR *, RENAME3res*); extern uint32_t zdr_READDIRPLUS3args (ZDR *, READDIRPLUS3args*); extern uint32_t zdr_entryplus3 (ZDR *, entryplus3*); extern uint32_t zdr_dirlistplus3 (ZDR *, dirlistplus3*); extern uint32_t zdr_READDIRPLUS3resok (ZDR *, READDIRPLUS3resok*); extern uint32_t zdr_READDIRPLUS3resfail (ZDR *, READDIRPLUS3resfail*); extern uint32_t zdr_READDIRPLUS3res (ZDR *, READDIRPLUS3res*); extern uint32_t zdr_READDIR3args (ZDR *, READDIR3args*); extern uint32_t zdr_entry3 (ZDR *, entry3*); extern uint32_t zdr_dirlist3 (ZDR *, dirlist3*); extern uint32_t zdr_READDIR3resok (ZDR *, READDIR3resok*); extern uint32_t zdr_READDIR3resfail (ZDR *, READDIR3resfail*); extern uint32_t zdr_READDIR3res (ZDR *, READDIR3res*); extern uint32_t zdr_LINK3args (ZDR *, LINK3args*); extern uint32_t zdr_LINK3resok (ZDR *, LINK3resok*); extern uint32_t zdr_LINK3resfail (ZDR *, LINK3resfail*); extern uint32_t zdr_LINK3res (ZDR *, LINK3res*); extern uint32_t zdr_sattrguard3 (ZDR *, sattrguard3*); extern uint32_t zdr_SETATTR3args (ZDR *, SETATTR3args*); extern uint32_t zdr_SETATTR3resok (ZDR *, SETATTR3resok*); extern uint32_t zdr_SETATTR3resfail (ZDR *, SETATTR3resfail*); extern uint32_t zdr_SETATTR3res (ZDR *, SETATTR3res*); extern uint32_t zdr_fhandle2 (ZDR *, fhandle2); extern uint32_t zdr_ftype2 (ZDR *, ftype2*); extern uint32_t zdr_fattr2 (ZDR *, fattr2*); extern uint32_t zdr_sattr2 (ZDR *, sattr2*); extern uint32_t zdr_filename2 (ZDR *, filename2*); extern uint32_t zdr_path2 (ZDR *, path2*); extern uint32_t zdr_nfsdata2 (ZDR *, nfsdata2*); extern uint32_t zdr_nfscookie2 (ZDR *, nfscookie2); extern uint32_t zdr_entry2 (ZDR *, entry2*); extern uint32_t zdr_diropargs2 (ZDR *, diropargs2*); extern uint32_t zdr_GETATTR2args (ZDR *, GETATTR2args*); extern uint32_t zdr_GETATTR2resok (ZDR *, GETATTR2resok*); extern uint32_t zdr_GETATTR2res (ZDR *, GETATTR2res*); extern uint32_t zdr_SETATTR2args (ZDR *, SETATTR2args*); extern uint32_t zdr_SETATTR2resok (ZDR *, SETATTR2resok*); extern uint32_t zdr_SETATTR2res (ZDR *, SETATTR2res*); extern uint32_t zdr_LOOKUP2args (ZDR *, LOOKUP2args*); extern uint32_t zdr_LOOKUP2resok (ZDR *, LOOKUP2resok*); extern uint32_t zdr_LOOKUP2res (ZDR *, LOOKUP2res*); extern uint32_t zdr_READLINK2args (ZDR *, READLINK2args*); extern uint32_t zdr_READLINK2resok (ZDR *, READLINK2resok*); extern uint32_t zdr_READLINK2res (ZDR *, READLINK2res*); extern uint32_t zdr_READ2args (ZDR *, READ2args*); extern uint32_t zdr_READ2resok (ZDR *, READ2resok*); extern uint32_t zdr_READ2res (ZDR *, READ2res*); extern uint32_t zdr_WRITE2args (ZDR *, WRITE2args*); extern uint32_t zdr_WRITE2resok (ZDR *, WRITE2resok*); extern uint32_t zdr_WRITE2res (ZDR *, WRITE2res*); extern uint32_t zdr_CREATE2args (ZDR *, CREATE2args*); extern uint32_t zdr_CREATE2resok (ZDR *, CREATE2resok*); extern uint32_t zdr_CREATE2res (ZDR *, CREATE2res*); extern uint32_t zdr_REMOVE2args (ZDR *, REMOVE2args*); extern uint32_t zdr_REMOVE2res (ZDR *, REMOVE2res*); extern uint32_t zdr_RENAME2args (ZDR *, RENAME2args*); extern uint32_t zdr_RENAME2res (ZDR *, RENAME2res*); extern uint32_t zdr_LINK2args (ZDR *, LINK2args*); extern uint32_t zdr_LINK2res (ZDR *, LINK2res*); extern uint32_t zdr_SYMLINK2args (ZDR *, SYMLINK2args*); extern uint32_t zdr_SYMLINK2res (ZDR *, SYMLINK2res*); extern uint32_t zdr_MKDIR2args (ZDR *, MKDIR2args*); extern uint32_t zdr_MKDIR2resok (ZDR *, MKDIR2resok*); extern uint32_t zdr_MKDIR2res (ZDR *, MKDIR2res*); extern uint32_t zdr_RMDIR2args (ZDR *, RMDIR2args*); extern uint32_t zdr_RMDIR2res (ZDR *, RMDIR2res*); extern uint32_t zdr_READDIR2args (ZDR *, READDIR2args*); extern uint32_t zdr_READDIR2resok (ZDR *, READDIR2resok*); extern uint32_t zdr_READDIR2res (ZDR *, READDIR2res*); extern uint32_t zdr_STATFS2args (ZDR *, STATFS2args*); extern uint32_t zdr_STATFS2resok (ZDR *, STATFS2resok*); extern uint32_t zdr_STATFS2res (ZDR *, STATFS2res*); extern uint32_t zdr_nfsacl_type (ZDR *, nfsacl_type*); extern uint32_t zdr_nfsacl_ace (ZDR *, nfsacl_ace*); extern uint32_t zdr_GETACL3args (ZDR *, GETACL3args*); extern uint32_t zdr_GETACL3resok (ZDR *, GETACL3resok*); extern uint32_t zdr_GETACL3res (ZDR *, GETACL3res*); extern uint32_t zdr_SETACL3args (ZDR *, SETACL3args*); extern uint32_t zdr_SETACL3resok (ZDR *, SETACL3resok*); extern uint32_t zdr_SETACL3res (ZDR *, SETACL3res*); #else /* K&R C */ extern uint32_t zdr_cookieverf3 (); extern uint32_t zdr_cookie3 (); extern uint32_t zdr_nfs_fh3 (); extern uint32_t zdr_filename3 (); extern uint32_t zdr_diropargs3 (); extern uint32_t zdr_ftype3 (); extern uint32_t zdr_mode3 (); extern uint32_t zdr_uid3 (); extern uint32_t zdr_gid3 (); extern uint32_t zdr_size3 (); extern uint32_t zdr_fileid3 (); extern uint32_t zdr_specdata3 (); extern uint32_t zdr_nfstime3 (); extern uint32_t zdr_fattr3 (); extern uint32_t zdr_post_op_attr (); extern uint32_t zdr_nfsstat3 (); extern uint32_t zdr_stable_how (); extern uint32_t zdr_offset3 (); extern uint32_t zdr_count3 (); extern uint32_t zdr_wcc_attr (); extern uint32_t zdr_pre_op_attr (); extern uint32_t zdr_wcc_data (); extern uint32_t zdr_WRITE3args (); extern uint32_t zdr_writeverf3 (); extern uint32_t zdr_WRITE3resok (); extern uint32_t zdr_WRITE3resfail (); extern uint32_t zdr_WRITE3res (); extern uint32_t zdr_LOOKUP3args (); extern uint32_t zdr_LOOKUP3resok (); extern uint32_t zdr_LOOKUP3resfail (); extern uint32_t zdr_LOOKUP3res (); extern uint32_t zdr_COMMIT3args (); extern uint32_t zdr_COMMIT3resok (); extern uint32_t zdr_COMMIT3resfail (); extern uint32_t zdr_COMMIT3res (); extern uint32_t zdr_ACCESS3args (); extern uint32_t zdr_ACCESS3resok (); extern uint32_t zdr_ACCESS3resfail (); extern uint32_t zdr_ACCESS3res (); extern uint32_t zdr_GETATTR3args (); extern uint32_t zdr_GETATTR3resok (); extern uint32_t zdr_GETATTR3res (); extern uint32_t zdr_time_how (); extern uint32_t zdr_set_mode3 (); extern uint32_t zdr_set_uid3 (); extern uint32_t zdr_set_gid3 (); extern uint32_t zdr_set_size3 (); extern uint32_t zdr_set_atime (); extern uint32_t zdr_set_mtime (); extern uint32_t zdr_sattr3 (); extern uint32_t zdr_createmode3 (); extern uint32_t zdr_createverf3 (); extern uint32_t zdr_createhow3 (); extern uint32_t zdr_CREATE3args (); extern uint32_t zdr_post_op_fh3 (); extern uint32_t zdr_CREATE3resok (); extern uint32_t zdr_CREATE3resfail (); extern uint32_t zdr_CREATE3res (); extern uint32_t zdr_REMOVE3args (); extern uint32_t zdr_REMOVE3resok (); extern uint32_t zdr_REMOVE3resfail (); extern uint32_t zdr_REMOVE3res (); extern uint32_t zdr_READ3args (); extern uint32_t zdr_READ3resok (); extern uint32_t zdr_READ3resfail (); extern uint32_t zdr_READ3res (); extern uint32_t zdr_FSINFO3args (); extern uint32_t zdr_FSINFO3resok (); extern uint32_t zdr_FSINFO3resfail (); extern uint32_t zdr_FSINFO3res (); extern uint32_t zdr_FSSTAT3args (); extern uint32_t zdr_FSSTAT3resok (); extern uint32_t zdr_FSSTAT3resfail (); extern uint32_t zdr_FSSTAT3res (); extern uint32_t zdr_PATHCONF3args (); extern uint32_t zdr_PATHCONF3resok (); extern uint32_t zdr_PATHCONF3resfail (); extern uint32_t zdr_PATHCONF3res (); extern uint32_t zdr_nfspath3 (); extern uint32_t zdr_symlinkdata3 (); extern uint32_t zdr_SYMLINK3args (); extern uint32_t zdr_SYMLINK3resok (); extern uint32_t zdr_SYMLINK3resfail (); extern uint32_t zdr_SYMLINK3res (); extern uint32_t zdr_READLINK3args (); extern uint32_t zdr_READLINK3resok (); extern uint32_t zdr_READLINK3resfail (); extern uint32_t zdr_READLINK3res (); extern uint32_t zdr_devicedata3 (); extern uint32_t zdr_mknoddata3 (); extern uint32_t zdr_MKNOD3args (); extern uint32_t zdr_MKNOD3resok (); extern uint32_t zdr_MKNOD3resfail (); extern uint32_t zdr_MKNOD3res (); extern uint32_t zdr_MKDIR3args (); extern uint32_t zdr_MKDIR3resok (); extern uint32_t zdr_MKDIR3resfail (); extern uint32_t zdr_MKDIR3res (); extern uint32_t zdr_RMDIR3args (); extern uint32_t zdr_RMDIR3resok (); extern uint32_t zdr_RMDIR3resfail (); extern uint32_t zdr_RMDIR3res (); extern uint32_t zdr_RENAME3args (); extern uint32_t zdr_RENAME3resok (); extern uint32_t zdr_RENAME3resfail (); extern uint32_t zdr_RENAME3res (); extern uint32_t zdr_READDIRPLUS3args (); extern uint32_t zdr_entryplus3 (); extern uint32_t zdr_dirlistplus3 (); extern uint32_t zdr_READDIRPLUS3resok (); extern uint32_t zdr_READDIRPLUS3resfail (); extern uint32_t zdr_READDIRPLUS3res (); extern uint32_t zdr_READDIR3args (); extern uint32_t zdr_entry3 (); extern uint32_t zdr_dirlist3 (); extern uint32_t zdr_READDIR3resok (); extern uint32_t zdr_READDIR3resfail (); extern uint32_t zdr_READDIR3res (); extern uint32_t zdr_LINK3args (); extern uint32_t zdr_LINK3resok (); extern uint32_t zdr_LINK3resfail (); extern uint32_t zdr_LINK3res (); extern uint32_t zdr_sattrguard3 (); extern uint32_t zdr_SETATTR3args (); extern uint32_t zdr_SETATTR3resok (); extern uint32_t zdr_SETATTR3resfail (); extern uint32_t zdr_SETATTR3res (); extern uint32_t zdr_fhandle2 (); extern uint32_t zdr_ftype2 (); extern uint32_t zdr_fattr2 (); extern uint32_t zdr_sattr2 (); extern uint32_t zdr_filename2 (); extern uint32_t zdr_path2 (); extern uint32_t zdr_nfsdata2 (); extern uint32_t zdr_nfscookie2 (); extern uint32_t zdr_entry2 (); extern uint32_t zdr_diropargs2 (); extern uint32_t zdr_GETATTR2args (); extern uint32_t zdr_GETATTR2resok (); extern uint32_t zdr_GETATTR2res (); extern uint32_t zdr_SETATTR2args (); extern uint32_t zdr_SETATTR2resok (); extern uint32_t zdr_SETATTR2res (); extern uint32_t zdr_LOOKUP2args (); extern uint32_t zdr_LOOKUP2resok (); extern uint32_t zdr_LOOKUP2res (); extern uint32_t zdr_READLINK2args (); extern uint32_t zdr_READLINK2resok (); extern uint32_t zdr_READLINK2res (); extern uint32_t zdr_READ2args (); extern uint32_t zdr_READ2resok (); extern uint32_t zdr_READ2res (); extern uint32_t zdr_WRITE2args (); extern uint32_t zdr_WRITE2resok (); extern uint32_t zdr_WRITE2res (); extern uint32_t zdr_CREATE2args (); extern uint32_t zdr_CREATE2resok (); extern uint32_t zdr_CREATE2res (); extern uint32_t zdr_REMOVE2args (); extern uint32_t zdr_REMOVE2res (); extern uint32_t zdr_RENAME2args (); extern uint32_t zdr_RENAME2res (); extern uint32_t zdr_LINK2args (); extern uint32_t zdr_LINK2res (); extern uint32_t zdr_SYMLINK2args (); extern uint32_t zdr_SYMLINK2res (); extern uint32_t zdr_MKDIR2args (); extern uint32_t zdr_MKDIR2resok (); extern uint32_t zdr_MKDIR2res (); extern uint32_t zdr_RMDIR2args (); extern uint32_t zdr_RMDIR2res (); extern uint32_t zdr_READDIR2args (); extern uint32_t zdr_READDIR2resok (); extern uint32_t zdr_READDIR2res (); extern uint32_t zdr_STATFS2args (); extern uint32_t zdr_STATFS2resok (); extern uint32_t zdr_STATFS2res (); extern uint32_t zdr_nfsacl_type (); extern uint32_t zdr_nfsacl_ace (); extern uint32_t zdr_GETACL3args (); extern uint32_t zdr_GETACL3resok (); extern uint32_t zdr_GETACL3res (); extern uint32_t zdr_SETACL3args (); extern uint32_t zdr_SETACL3resok (); extern uint32_t zdr_SETACL3res (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_NFS_H_RPCGEN */ libnfs-libnfs-1.9.8/nfs/nfs.c000066400000000000000000001153201255745034100160110ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef WIN32 #include "win32_compat.h" #else #include #endif/*WIN32*/ #include #include #include #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" #include "libnfs-raw-nfs.h" char *nfsstat3_to_str(int error) { switch (error) { case NFS3_OK: return "NFS3_OK"; break; case NFS3ERR_PERM: return "NFS3ERR_PERM"; break; case NFS3ERR_NOENT: return "NFS3ERR_NOENT"; break; case NFS3ERR_IO: return "NFS3ERR_IO"; break; case NFS3ERR_NXIO: return "NFS3ERR_NXIO"; break; case NFS3ERR_ACCES: return "NFS3ERR_ACCES"; break; case NFS3ERR_EXIST: return "NFS3ERR_EXIST"; break; case NFS3ERR_XDEV: return "NFS3ERR_XDEV"; break; case NFS3ERR_NODEV: return "NFS3ERR_NODEV"; break; case NFS3ERR_NOTDIR: return "NFS3ERR_NOTDIR"; break; case NFS3ERR_ISDIR: return "NFS3ERR_ISDIR"; break; case NFS3ERR_INVAL: return "NFS3ERR_INVAL"; break; case NFS3ERR_FBIG: return "NFS3ERR_FBIG"; break; case NFS3ERR_NOSPC: return "NFS3ERR_NOSPC"; break; case NFS3ERR_ROFS: return "NFS3ERR_ROFS"; break; case NFS3ERR_MLINK: return "NFS3ERR_MLINK"; break; case NFS3ERR_NAMETOOLONG: return "NFS3ERR_NAMETOOLONG"; break; case NFS3ERR_NOTEMPTY: return "NFS3ERR_NOTEMPTY"; break; case NFS3ERR_DQUOT: return "NFS3ERR_DQUOT"; break; case NFS3ERR_STALE: return "NFS3ERR_STALE"; break; case NFS3ERR_REMOTE: return "NFS3ERR_REMOTE"; break; case NFS3ERR_BADHANDLE: return "NFS3ERR_BADHANDLE"; break; case NFS3ERR_NOT_SYNC: return "NFS3ERR_NOT_SYNC"; break; case NFS3ERR_BAD_COOKIE: return "NFS3ERR_BAD_COOKIE"; break; case NFS3ERR_NOTSUPP: return "NFS3ERR_NOTSUPP"; break; case NFS3ERR_TOOSMALL: return "NFS3ERR_TOOSMALL"; break; case NFS3ERR_SERVERFAULT: return "NFS3ERR_SERVERFAULT"; break; case NFS3ERR_BADTYPE: return "NFS3ERR_BADTYPE"; break; case NFS3ERR_JUKEBOX: return "NFS3ERR_JUKEBOX"; break; }; return "unknown nfs error"; } int nfsstat3_to_errno(int error) { switch (error) { case NFS3_OK: return 0; break; case NFS3ERR_PERM: return -EPERM; break; case NFS3ERR_NOENT: return -ENOENT; break; case NFS3ERR_IO: return -EIO; break; case NFS3ERR_NXIO: return -ENXIO; break; case NFS3ERR_ACCES: return -EACCES; break; case NFS3ERR_EXIST: return -EEXIST; break; case NFS3ERR_XDEV: return -EXDEV; break; case NFS3ERR_NODEV: return -ENODEV; break; case NFS3ERR_NOTDIR: return -ENOTDIR; break; case NFS3ERR_ISDIR: return -EISDIR; break; case NFS3ERR_INVAL: return -EINVAL; break; case NFS3ERR_FBIG: return -EFBIG; break; case NFS3ERR_NOSPC: return -ENOSPC; break; case NFS3ERR_ROFS: return -EROFS; break; case NFS3ERR_MLINK: return -EMLINK; break; case NFS3ERR_NAMETOOLONG: return -ENAMETOOLONG; break; case NFS3ERR_NOTEMPTY: return -ENOTEMPTY; break; case NFS3ERR_DQUOT: return -ERANGE; break; case NFS3ERR_STALE: return -EIO; break; case NFS3ERR_REMOTE: return -EIO; break; case NFS3ERR_BADHANDLE: return -EIO; break; case NFS3ERR_NOT_SYNC: return -EIO; break; case NFS3ERR_BAD_COOKIE: return -EIO; break; case NFS3ERR_NOTSUPP: return -EINVAL; break; case NFS3ERR_TOOSMALL: return -EIO; break; case NFS3ERR_SERVERFAULT: return -EIO; break; case NFS3ERR_BADTYPE: return -EINVAL; break; case NFS3ERR_JUKEBOX: return -EAGAIN; break; }; return -ERANGE; } /* * NFSv3 */ int rpc_nfs3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/NULL call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/NULL call"); rpc_free_pdu(rpc, pdu); return -2; } return 0; } int rpc_nfs_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { return rpc_nfs3_null_async(rpc, cb, private_data); } int rpc_nfs3_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct GETATTR3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_GETATTR, cb, private_data, (zdrproc_t)zdr_GETATTR3res, sizeof(GETATTR3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/GETATTR call"); return -1; } if (zdr_GETATTR3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode GETATTR3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/GETATTR call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) { GETATTR3args args; memset(&args, 0, sizeof(GETATTR3args)); args.object.data.data_len = fh->data.data_len; args.object.data.data_val = fh->data.data_val; return rpc_nfs3_getattr_async(rpc, cb, &args, private_data); } int rpc_nfs3_pathconf_async(struct rpc_context *rpc, rpc_cb cb, struct PATHCONF3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_PATHCONF, cb, private_data, (zdrproc_t)zdr_PATHCONF3res, sizeof(PATHCONF3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/PATHCONF call"); return -1; } if (zdr_PATHCONF3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode PATHCONF3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/PATHCONF call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_pathconf_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) { PATHCONF3args args; memset(&args, 0, sizeof(PATHCONF3args)); args.object.data.data_len = fh->data.data_len; args.object.data.data_val = fh->data.data_val; return rpc_nfs3_pathconf_async(rpc, cb, &args, private_data); } int rpc_nfs3_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct LOOKUP3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_LOOKUP, cb, private_data, (zdrproc_t)zdr_LOOKUP3res, sizeof(LOOKUP3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/LOOKUP call"); return -1; } if (zdr_LOOKUP3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode LOOKUP3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/LOOKUP call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *name, void *private_data) { LOOKUP3args args; memset(&args, 0, sizeof(LOOKUP3args)); args.what.dir.data.data_len = fh->data.data_len; args.what.dir.data.data_val = fh->data.data_val; args.what.name = name; return rpc_nfs3_lookup_async(rpc, cb, &args, private_data); } int rpc_nfs3_access_async(struct rpc_context *rpc, rpc_cb cb, struct ACCESS3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_ACCESS, cb, private_data, (zdrproc_t)zdr_ACCESS3res, sizeof(ACCESS3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/ACCESS call"); return -1; } if (zdr_ACCESS3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode ACCESS3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/ACCESS call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_access_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, int access, void *private_data) { ACCESS3args args; memset(&args, 0, sizeof(ACCESS3args)); args.object.data.data_len = fh->data.data_len; args.object.data.data_val = fh->data.data_val; args.access = access; return rpc_nfs3_access_async(rpc, cb, &args, private_data); } int rpc_nfs3_read_async(struct rpc_context *rpc, rpc_cb cb, struct READ3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READ, cb, private_data, (zdrproc_t)zdr_READ3res, sizeof(READ3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/READ call"); return -1; } if (zdr_READ3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode READ3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/READ call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_read_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t offset, uint64_t count, void *private_data) { READ3args args; memset(&args, 0, sizeof(READ3args)); args.file.data.data_len = fh->data.data_len; args.file.data.data_val = fh->data.data_val; args.offset = offset; args.count = count; return rpc_nfs3_read_async(rpc, cb, &args, private_data); } int rpc_nfs3_write_async(struct rpc_context *rpc, rpc_cb cb, struct WRITE3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE3res, sizeof(WRITE3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/WRITE call"); return -1; } if (zdr_WRITE3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode WRITE3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/WRITE call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_write_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *buf, uint64_t offset, uint64_t count, int stable_how, void *private_data) { WRITE3args args; memset(&args, 0, sizeof(WRITE3args)); args.file.data.data_len = fh->data.data_len; args.file.data.data_val = fh->data.data_val; args.offset = offset; args.count = count; args.stable = stable_how; args.data.data_len = count; args.data.data_val = buf; return rpc_nfs3_write_async(rpc, cb, &args, private_data); } int rpc_nfs3_commit_async(struct rpc_context *rpc, rpc_cb cb, struct COMMIT3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_COMMIT, cb, private_data, (zdrproc_t)zdr_COMMIT3res, sizeof(COMMIT3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/COMMIT call"); return -1; } if (zdr_COMMIT3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode COMMIT3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/COMMIT call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_commit_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) { COMMIT3args args; memset(&args, 0, sizeof(COMMIT3args)); args.file.data.data_len = fh->data.data_len; args.file.data.data_val = fh->data.data_val; args.offset = 0; args.count = 0; return rpc_nfs3_commit_async(rpc, cb, &args, private_data); } int rpc_nfs3_setattr_async(struct rpc_context *rpc, rpc_cb cb, SETATTR3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_SETATTR, cb, private_data, (zdrproc_t)zdr_SETATTR3res, sizeof(SETATTR3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/SETATTR call"); return -1; } if (zdr_SETATTR3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode SETATTR3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/SETATTR call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_setattr_async(struct rpc_context *rpc, rpc_cb cb, SETATTR3args *args, void *private_data) { return rpc_nfs3_setattr_async(rpc, cb, args, private_data); } int rpc_nfs3_mkdir_async(struct rpc_context *rpc, rpc_cb cb, MKDIR3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_MKDIR, cb, private_data, (zdrproc_t)zdr_MKDIR3res, sizeof(MKDIR3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/MKDIR call"); return -1; } if (zdr_MKDIR3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode MKDIR3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/MKDIR call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_mkdir_async(struct rpc_context *rpc, rpc_cb cb, MKDIR3args *args, void *private_data) { return rpc_nfs3_mkdir_async(rpc, cb, args, private_data); } int rpc_nfs3_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct RMDIR3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_RMDIR, cb, private_data, (zdrproc_t)zdr_RMDIR3res, sizeof(RMDIR3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/RMDIR call"); return -1; } if (zdr_RMDIR3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode RMDIR3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/RMDIR call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *dir, void *private_data) { RMDIR3args args; memset(&args, 0, sizeof(RMDIR3args)); args.object.dir.data.data_len = fh->data.data_len; args.object.dir.data.data_val = fh->data.data_val; args.object.name = dir; return rpc_nfs3_rmdir_async(rpc, cb, &args, private_data); } int rpc_nfs3_create_async(struct rpc_context *rpc, rpc_cb cb, CREATE3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_CREATE, cb, private_data, (zdrproc_t)zdr_CREATE3res, sizeof(CREATE3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/CREATE call"); return -1; } if (zdr_CREATE3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode CREATE3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/CREATE call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_create_async(struct rpc_context *rpc, rpc_cb cb, CREATE3args *args, void *private_data) { return rpc_nfs3_create_async(rpc, cb, args, private_data); } int rpc_nfs3_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct MKNOD3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_MKNOD, cb, private_data, (zdrproc_t)zdr_MKNOD3res, sizeof(MKNOD3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/MKNOD call"); return -1; } if (zdr_MKNOD3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode MKNOD3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/MKNOD call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_mknod_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, int mode, int major, int minor, void *private_data) { MKNOD3args args; memset(&args, 0, sizeof(MKNOD3args)); args.where.dir.data.data_len = fh->data.data_len; args.where.dir.data.data_val = fh->data.data_val; args.where.name = file; switch (mode & S_IFMT) { case S_IFCHR: args.what.type = NF3CHR; args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_it = 1; args.what.mknoddata3_u.chr_device.dev_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); args.what.mknoddata3_u.chr_device.spec.specdata1 = major; args.what.mknoddata3_u.chr_device.spec.specdata2 = minor; break; case S_IFBLK: args.what.type = NF3BLK; args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_it = 1; args.what.mknoddata3_u.blk_device.dev_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); args.what.mknoddata3_u.blk_device.spec.specdata1 = major; args.what.mknoddata3_u.blk_device.spec.specdata2 = minor; case S_IFSOCK: args.what.type = NF3SOCK; args.what.mknoddata3_u.sock_attributes.mode.set_it = 1; args.what.mknoddata3_u.sock_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); break; case S_IFIFO: args.what.type = NF3FIFO; args.what.mknoddata3_u.pipe_attributes.mode.set_it = 1; args.what.mknoddata3_u.pipe_attributes.mode.set_mode3_u.mode = mode & (S_IRUSR|S_IWUSR|S_IXUSR|S_IRGRP|S_IWGRP|S_IXGRP|S_IROTH|S_IWOTH|S_IXOTH); break; default: rpc_set_error(rpc, "Invalid file type for NFS3/MKNOD call"); return -1; } return rpc_nfs3_mknod_async(rpc, cb, &args, private_data); } int rpc_nfs3_remove_async(struct rpc_context *rpc, rpc_cb cb, struct REMOVE3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_REMOVE, cb, private_data, (zdrproc_t)zdr_REMOVE3res, sizeof(REMOVE3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/REMOVE call"); return -1; } if (zdr_REMOVE3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode REMOVE3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/REMOVE call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_remove_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, char *file, void *private_data) { REMOVE3args args; memset(&args, 0, sizeof(REMOVE3args)); args.object.dir.data.data_len = fh->data.data_len; args.object.dir.data.data_val = fh->data.data_val; args.object.name = file; return rpc_nfs3_remove_async(rpc, cb, &args, private_data); } int rpc_nfs3_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct READDIR3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READDIR, cb, private_data, (zdrproc_t)zdr_READDIR3res, sizeof(READDIR3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/READDIR call"); return -1; } if (zdr_READDIR3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode READDIR3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/READDIR call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data) { READDIR3args args; memset(&args, 0, sizeof(READDIR3args)); args.dir.data.data_len = fh->data.data_len; args.dir.data.data_val = fh->data.data_val; args.cookie = cookie; memcpy(&args.cookieverf, cookieverf, sizeof(cookieverf3)); args.count = count; return rpc_nfs3_readdir_async(rpc, cb, &args, private_data); } int rpc_nfs3_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct READDIRPLUS3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READDIRPLUS, cb, private_data, (zdrproc_t)zdr_READDIRPLUS3res, sizeof(READDIRPLUS3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/READDIRPLUS call"); return -1; } if (zdr_READDIRPLUS3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode READDIRPLUS3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/READDIRPLUS call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_readdirplus_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, uint64_t cookie, char *cookieverf, int count, void *private_data) { READDIRPLUS3args args; memset(&args, 0, sizeof(READDIRPLUS3args)); args.dir.data.data_len = fh->data.data_len; args.dir.data.data_val = fh->data.data_val; args.cookie = cookie; memcpy(&args.cookieverf, cookieverf, sizeof(cookieverf3)); args.dircount = count; args.maxcount = count * 8; return rpc_nfs3_readdirplus_async(rpc, cb, &args, private_data); } int rpc_nfs3_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct FSSTAT3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_FSSTAT, cb, private_data, (zdrproc_t)zdr_FSSTAT3res, sizeof(FSSTAT3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/FSSTAT call"); return -1; } if (zdr_FSSTAT3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode FSSTAT3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/FSSTAT call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_fsstat_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) { FSSTAT3args args; memset(&args, 0, sizeof(FSSTAT3args)); args.fsroot.data.data_len = fh->data.data_len; args.fsroot.data.data_val = fh->data.data_val; return rpc_nfs3_fsstat_async(rpc, cb, &args, private_data); } int rpc_nfs3_fsinfo_async(struct rpc_context *rpc, rpc_cb cb, struct FSINFO3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_FSINFO, cb, private_data, (zdrproc_t)zdr_FSINFO3res, sizeof(FSINFO3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/FSINFO call"); return -1; } if (zdr_FSINFO3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode FSINFO3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/FSINFO call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_fsinfo_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *fh, void *private_data) { FSINFO3args args; memset(&args, 0, sizeof(FSINFO3args)); args.fsroot.data.data_len = fh->data.data_len; args.fsroot.data.data_val = fh->data.data_val; return rpc_nfs3_fsinfo_async(rpc, cb, &args, private_data); } int rpc_nfs3_readlink_async(struct rpc_context *rpc, rpc_cb cb, READLINK3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_READLINK, cb, private_data, (zdrproc_t)zdr_READLINK3res, sizeof(READLINK3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/READLINK call"); return -1; } if (zdr_READLINK3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode READLINK3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/READLINK call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_readlink_async(struct rpc_context *rpc, rpc_cb cb, READLINK3args *args, void *private_data) { return rpc_nfs3_readlink_async(rpc, cb, args, private_data); } int rpc_nfs3_symlink_async(struct rpc_context *rpc, rpc_cb cb, SYMLINK3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_SYMLINK, cb, private_data, (zdrproc_t)zdr_SYMLINK3res, sizeof(SYMLINK3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/SYMLINK call"); return -1; } if (zdr_SYMLINK3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode SYMLINK3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/SYMLINK call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_symlink_async(struct rpc_context *rpc, rpc_cb cb, SYMLINK3args *args, void *private_data) { return rpc_nfs3_symlink_async(rpc, cb, args, private_data); } int rpc_nfs3_rename_async(struct rpc_context *rpc, rpc_cb cb, struct RENAME3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_RENAME, cb, private_data, (zdrproc_t)zdr_RENAME3res, sizeof(RENAME3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/RENAME call"); return -1; } if (zdr_RENAME3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode RENAME3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/RENAME call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_rename_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *olddir, char *oldname, struct nfs_fh3 *newdir, char *newname, void *private_data) { RENAME3args args; memset(&args, 0, sizeof(RENAME3args)); args.from.dir.data.data_len = olddir->data.data_len; args.from.dir.data.data_val = olddir->data.data_val; args.from.name = oldname; args.to.dir.data.data_len = newdir->data.data_len; args.to.dir.data.data_val = newdir->data.data_val; args.to.name = newname; return rpc_nfs3_rename_async(rpc, cb, &args, private_data); } int rpc_nfs3_link_async(struct rpc_context *rpc, rpc_cb cb, struct LINK3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V3, NFS3_LINK, cb, private_data, (zdrproc_t)zdr_LINK3res, sizeof(LINK3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/LINK call"); return -1; } if (zdr_LINK3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode LINK3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS3/LINK call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs_link_async(struct rpc_context *rpc, rpc_cb cb, struct nfs_fh3 *file, struct nfs_fh3 *newdir, char *newname, void *private_data) { LINK3args args; memset(&args, 0, sizeof(LINK3args)); args.file.data.data_len = file->data.data_len; args.file.data.data_val = file->data.data_val; args.link.dir.data.data_len = newdir->data.data_len; args.link.dir.data.data_val = newdir->data.data_val; args.link.name = newname; return rpc_nfs3_link_async(rpc, cb, &args, private_data); } /* * NFSv2 */ int rpc_nfs2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/NULL call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/NULL call"); rpc_free_pdu(rpc, pdu); return -2; } return 0; } int rpc_nfs2_getattr_async(struct rpc_context *rpc, rpc_cb cb, struct GETATTR2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_GETATTR, cb, private_data, (zdrproc_t)zdr_GETATTR2res, sizeof(GETATTR2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/GETATTR call"); return -1; } if (zdr_GETATTR2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode GETATTR2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/GETATTR call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_setattr_async(struct rpc_context *rpc, rpc_cb cb, SETATTR2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_SETATTR, cb, private_data, (zdrproc_t)zdr_SETATTR2res, sizeof(SETATTR2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/SETATTR call"); return -1; } if (zdr_SETATTR2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode SETATTR2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/SETATTR call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_lookup_async(struct rpc_context *rpc, rpc_cb cb, struct LOOKUP2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_LOOKUP, cb, private_data, (zdrproc_t)zdr_LOOKUP2res, sizeof(LOOKUP2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/LOOKUP call"); return -1; } if (zdr_LOOKUP2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode LOOKUP2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/LOOKUP call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_readlink_async(struct rpc_context *rpc, rpc_cb cb, READLINK2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_READLINK, cb, private_data, (zdrproc_t)zdr_READLINK2res, sizeof(READLINK2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/READLINK call"); return -1; } if (zdr_READLINK2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode READLINK2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/READLINK call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_read_async(struct rpc_context *rpc, rpc_cb cb, struct READ2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_READ, cb, private_data, (zdrproc_t)zdr_READ2res, sizeof(READ2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/READ call"); return -1; } if (zdr_READ2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode READ2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/READ call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_write_async(struct rpc_context *rpc, rpc_cb cb, struct WRITE2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_WRITE, cb, private_data, (zdrproc_t)zdr_WRITE2res, sizeof(WRITE2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/WRITE call"); return -1; } if (zdr_WRITE2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode WRITE2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/WRITE call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_create_async(struct rpc_context *rpc, rpc_cb cb, CREATE2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_CREATE, cb, private_data, (zdrproc_t)zdr_CREATE2res, sizeof(CREATE2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/CREATE call"); return -1; } if (zdr_CREATE2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode CREATE2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/CREATE call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_remove_async(struct rpc_context *rpc, rpc_cb cb, struct REMOVE2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_REMOVE, cb, private_data, (zdrproc_t)zdr_REMOVE2res, sizeof(REMOVE2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS3/REMOVE call"); return -1; } if (zdr_REMOVE2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode REMOVE2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/REMOVE call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_rename_async(struct rpc_context *rpc, rpc_cb cb, struct RENAME2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_RENAME, cb, private_data, (zdrproc_t)zdr_RENAME2res, sizeof(RENAME2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/RENAME call"); return -1; } if (zdr_RENAME2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode RENAME2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/RENAME call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_link_async(struct rpc_context *rpc, rpc_cb cb, LINK2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_LINK, cb, private_data, (zdrproc_t)zdr_LINK2res, sizeof(LINK2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/LINK call"); return -1; } if (zdr_LINK2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode LINK2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/LINK call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_symlink_async(struct rpc_context *rpc, rpc_cb cb, SYMLINK2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_SYMLINK, cb, private_data, (zdrproc_t)zdr_SYMLINK2res, sizeof(SYMLINK2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/SYMLINK call"); return -1; } if (zdr_SYMLINK2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode SYMLINK2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/SYMLINK call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_mkdir_async(struct rpc_context *rpc, rpc_cb cb, MKDIR2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_MKDIR, cb, private_data, (zdrproc_t)zdr_MKDIR2res, sizeof(MKDIR2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/MKDIR call"); return -1; } if (zdr_MKDIR2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode MKDIR2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/MKDIR call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_rmdir_async(struct rpc_context *rpc, rpc_cb cb, struct RMDIR2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_RMDIR, cb, private_data, (zdrproc_t)zdr_RMDIR2res, sizeof(RMDIR2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/RMDIR call"); return -1; } if (zdr_RMDIR2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode RMDIR2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/RMDIR call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_readdir_async(struct rpc_context *rpc, rpc_cb cb, struct READDIR2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_READDIR, cb, private_data, (zdrproc_t)zdr_READDIR2res, sizeof(READDIR2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/READDIR call"); return -1; } if (zdr_READDIR2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode READDIR2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/READDIR call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_nfs2_statfs_async(struct rpc_context *rpc, rpc_cb cb, struct STATFS2args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFS_PROGRAM, NFS_V2, NFS2_STATFS, cb, private_data, (zdrproc_t)zdr_STATFS2res, sizeof(STATFS2res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for NFS2/STATFS call"); return -1; } if (zdr_STATFS2args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode STATFS2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for NFS2/STATFS call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } libnfs-libnfs-1.9.8/nfs/nfs.x000066400000000000000000000533071255745034100160440ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * NFS v3 Definitions */ const NFS3_FHSIZE = 64; /* Maximum bytes in a V3 file handle */ const NFS3_WRITEVERFSIZE = 8; const NFS3_CREATEVERFSIZE = 8; const NFS3_COOKIEVERFSIZE = 8; typedef opaque cookieverf3[NFS3_COOKIEVERFSIZE]; typedef uint64_t cookie3; struct nfs_fh3 { opaque data; }; typedef string filename3<>; struct diropargs3 { nfs_fh3 dir; filename3 name; }; enum ftype3 { NF3REG = 1, NF3DIR = 2, NF3BLK = 3, NF3CHR = 4, NF3LNK = 5, NF3SOCK = 6, NF3FIFO = 7 }; typedef unsigned int mode3; typedef unsigned int uid3; typedef unsigned int gid3; typedef uint64_t size3; typedef uint64_t fileid3; struct specdata3 { unsigned int specdata1; unsigned int specdata2; }; struct nfstime3 { unsigned int seconds; unsigned int nseconds; }; struct fattr3 { ftype3 type; mode3 mode; unsigned int nlink; uid3 uid; gid3 gid; size3 size; size3 used; specdata3 rdev; uint64_t fsid; fileid3 fileid; nfstime3 atime; nfstime3 mtime; nfstime3 ctime; }; union post_op_attr switch (bool attributes_follow) { case TRUE: fattr3 attributes; case FALSE: void; }; enum nfsstat3 { NFS3_OK = 0, NFS3ERR_PERM = 1, NFS3ERR_NOENT = 2, NFS3ERR_IO = 5, NFS3ERR_NXIO = 6, NFS3ERR_ACCES = 13, NFS3ERR_EXIST = 17, NFS3ERR_XDEV = 18, NFS3ERR_NODEV = 19, NFS3ERR_NOTDIR = 20, NFS3ERR_ISDIR = 21, NFS3ERR_INVAL = 22, NFS3ERR_FBIG = 27, NFS3ERR_NOSPC = 28, NFS3ERR_ROFS = 30, NFS3ERR_MLINK = 31, NFS3ERR_NAMETOOLONG = 63, NFS3ERR_NOTEMPTY = 66, NFS3ERR_DQUOT = 69, NFS3ERR_STALE = 70, NFS3ERR_REMOTE = 71, NFS3ERR_BADHANDLE = 10001, NFS3ERR_NOT_SYNC = 10002, NFS3ERR_BAD_COOKIE = 10003, NFS3ERR_NOTSUPP = 10004, NFS3ERR_TOOSMALL = 10005, NFS3ERR_SERVERFAULT = 10006, NFS3ERR_BADTYPE = 10007, NFS3ERR_JUKEBOX = 10008 }; enum stable_how { UNSTABLE = 0, DATA_SYNC = 1, FILE_SYNC = 2 }; typedef uint64_t offset3; typedef unsigned int count3; struct wcc_attr { size3 size; nfstime3 mtime; nfstime3 ctime; }; union pre_op_attr switch (bool attributes_follow) { case TRUE: wcc_attr attributes; case FALSE: void; }; struct wcc_data { pre_op_attr before; post_op_attr after; }; struct WRITE3args { nfs_fh3 file; offset3 offset; count3 count; stable_how stable; opaque data<>; }; typedef opaque writeverf3[NFS3_WRITEVERFSIZE]; struct WRITE3resok { wcc_data file_wcc; count3 count; stable_how committed; writeverf3 verf; }; struct WRITE3resfail { wcc_data file_wcc; }; union WRITE3res switch (nfsstat3 status) { case NFS3_OK: WRITE3resok resok; default: WRITE3resfail resfail; }; struct LOOKUP3args { diropargs3 what; }; struct LOOKUP3resok { nfs_fh3 object; post_op_attr obj_attributes; post_op_attr dir_attributes; }; struct LOOKUP3resfail { post_op_attr dir_attributes; }; union LOOKUP3res switch (nfsstat3 status) { case NFS3_OK: LOOKUP3resok resok; default: LOOKUP3resfail resfail; }; struct COMMIT3args { nfs_fh3 file; offset3 offset; count3 count; }; struct COMMIT3resok { wcc_data file_wcc; writeverf3 verf; }; struct COMMIT3resfail { wcc_data file_wcc; }; union COMMIT3res switch (nfsstat3 status) { case NFS3_OK: COMMIT3resok resok; default: COMMIT3resfail resfail; }; const ACCESS3_READ = 0x0001; const ACCESS3_LOOKUP = 0x0002; const ACCESS3_MODIFY = 0x0004; const ACCESS3_EXTEND = 0x0008; const ACCESS3_DELETE = 0x0010; const ACCESS3_EXECUTE = 0x0020; struct ACCESS3args { nfs_fh3 object; unsigned int access; }; struct ACCESS3resok { post_op_attr obj_attributes; unsigned int access; }; struct ACCESS3resfail { post_op_attr obj_attributes; }; union ACCESS3res switch (nfsstat3 status) { case NFS3_OK: ACCESS3resok resok; default: ACCESS3resfail resfail; }; struct GETATTR3args { nfs_fh3 object; }; struct GETATTR3resok { fattr3 obj_attributes; }; union GETATTR3res switch (nfsstat3 status) { case NFS3_OK: GETATTR3resok resok; default: void; }; enum time_how { DONT_CHANGE = 0, SET_TO_SERVER_TIME = 1, SET_TO_CLIENT_TIME = 2 }; union set_mode3 switch (bool set_it) { case TRUE: mode3 mode; default: void; }; union set_uid3 switch (bool set_it) { case TRUE: uid3 uid; default: void; }; union set_gid3 switch (bool set_it) { case TRUE: gid3 gid; default: void; }; union set_size3 switch (bool set_it) { case TRUE: size3 size; default: void; }; union set_atime switch (time_how set_it) { case SET_TO_CLIENT_TIME: nfstime3 atime; default: void; }; union set_mtime switch (time_how set_it) { case SET_TO_CLIENT_TIME: nfstime3 mtime; default: void; }; struct sattr3 { set_mode3 mode; set_uid3 uid; set_gid3 gid; set_size3 size; set_atime atime; set_mtime mtime; }; enum createmode3 { UNCHECKED = 0, GUARDED = 1, EXCLUSIVE = 2 }; typedef opaque createverf3[NFS3_CREATEVERFSIZE]; union createhow3 switch (createmode3 mode) { case UNCHECKED: sattr3 obj_attributes; case GUARDED: sattr3 g_obj_attributes; case EXCLUSIVE: createverf3 verf; }; struct CREATE3args { diropargs3 where; createhow3 how; }; union post_op_fh3 switch (bool handle_follows) { case TRUE: nfs_fh3 handle; case FALSE: void; }; struct CREATE3resok { post_op_fh3 obj; post_op_attr obj_attributes; wcc_data dir_wcc; }; struct CREATE3resfail { wcc_data dir_wcc; }; union CREATE3res switch (nfsstat3 status) { case NFS3_OK: CREATE3resok resok; default: CREATE3resfail resfail; }; struct REMOVE3args { diropargs3 object; }; struct REMOVE3resok { wcc_data dir_wcc; }; struct REMOVE3resfail { wcc_data dir_wcc; }; union REMOVE3res switch (nfsstat3 status) { case NFS3_OK: REMOVE3resok resok; default: REMOVE3resfail resfail; }; struct READ3args { nfs_fh3 file; offset3 offset; count3 count; }; struct READ3resok { post_op_attr file_attributes; count3 count; bool eof; opaque data<>; }; struct READ3resfail { post_op_attr file_attributes; }; union READ3res switch (nfsstat3 status) { case NFS3_OK: READ3resok resok; default: READ3resfail resfail; }; const FSF3_LINK = 0x0001; const FSF3_SYMLINK = 0x0002; const FSF3_HOMOGENEOUS = 0x0008; const FSF3_CANSETTIME = 0x0010; struct FSINFO3args { nfs_fh3 fsroot; }; struct FSINFO3resok { post_op_attr obj_attributes; unsigned int rtmax; unsigned int rtpref; unsigned int rtmult; unsigned int wtmax; unsigned int wtpref; unsigned int wtmult; unsigned int dtpref; size3 maxfilesize; nfstime3 time_delta; unsigned int properties; }; struct FSINFO3resfail { post_op_attr obj_attributes; }; union FSINFO3res switch (nfsstat3 status) { case NFS3_OK: FSINFO3resok resok; default: FSINFO3resfail resfail; }; struct FSSTAT3args { nfs_fh3 fsroot; }; struct FSSTAT3resok { post_op_attr obj_attributes; size3 tbytes; size3 fbytes; size3 abytes; size3 tfiles; size3 ffiles; size3 afiles; unsigned int invarsec; }; struct FSSTAT3resfail { post_op_attr obj_attributes; }; union FSSTAT3res switch (nfsstat3 status) { case NFS3_OK: FSSTAT3resok resok; default: FSSTAT3resfail resfail; }; struct PATHCONF3args { nfs_fh3 object; }; struct PATHCONF3resok { post_op_attr obj_attributes; unsigned int linkmax; unsigned int name_max; bool no_trunc; bool chown_restricted; bool case_insensitive; bool case_preserving; }; struct PATHCONF3resfail { post_op_attr obj_attributes; }; union PATHCONF3res switch (nfsstat3 status) { case NFS3_OK: PATHCONF3resok resok; default: PATHCONF3resfail resfail; }; typedef string nfspath3<>; struct symlinkdata3 { sattr3 symlink_attributes; nfspath3 symlink_data; }; struct SYMLINK3args { diropargs3 where; symlinkdata3 symlink; }; struct SYMLINK3resok { post_op_fh3 obj; post_op_attr obj_attributes; wcc_data dir_wcc; }; struct SYMLINK3resfail { wcc_data dir_wcc; }; union SYMLINK3res switch (nfsstat3 status) { case NFS3_OK: SYMLINK3resok resok; default: SYMLINK3resfail resfail; }; struct READLINK3args { nfs_fh3 symlink; }; struct READLINK3resok { post_op_attr symlink_attributes; nfspath3 data; }; struct READLINK3resfail { post_op_attr symlink_attributes; }; union READLINK3res switch (nfsstat3 status) { case NFS3_OK: READLINK3resok resok; default: READLINK3resfail resfail; }; struct devicedata3 { sattr3 dev_attributes; specdata3 spec; }; union mknoddata3 switch (ftype3 type) { case NF3CHR: devicedata3 chr_device; case NF3BLK: devicedata3 blk_device; case NF3SOCK: sattr3 sock_attributes; case NF3FIFO: sattr3 pipe_attributes; default: void; }; struct MKNOD3args { diropargs3 where; mknoddata3 what; }; struct MKNOD3resok { post_op_fh3 obj; post_op_attr obj_attributes; wcc_data dir_wcc; }; struct MKNOD3resfail { wcc_data dir_wcc; }; union MKNOD3res switch (nfsstat3 status) { case NFS3_OK: MKNOD3resok resok; default: MKNOD3resfail resfail; }; struct MKDIR3args { diropargs3 where; sattr3 attributes; }; struct MKDIR3resok { post_op_fh3 obj; post_op_attr obj_attributes; wcc_data dir_wcc; }; struct MKDIR3resfail { wcc_data dir_wcc; }; union MKDIR3res switch (nfsstat3 status) { case NFS3_OK: MKDIR3resok resok; default: MKDIR3resfail resfail; }; struct RMDIR3args { diropargs3 object; }; struct RMDIR3resok { wcc_data dir_wcc; }; struct RMDIR3resfail { wcc_data dir_wcc; }; union RMDIR3res switch (nfsstat3 status) { case NFS3_OK: RMDIR3resok resok; default: RMDIR3resfail resfail; }; struct RENAME3args { diropargs3 from; diropargs3 to; }; struct RENAME3resok { wcc_data fromdir_wcc; wcc_data todir_wcc; }; struct RENAME3resfail { wcc_data fromdir_wcc; wcc_data todir_wcc; }; union RENAME3res switch (nfsstat3 status) { case NFS3_OK: RENAME3resok resok; default: RENAME3resfail resfail; }; struct READDIRPLUS3args { nfs_fh3 dir; cookie3 cookie; cookieverf3 cookieverf; count3 dircount; count3 maxcount; }; struct entryplus3 { fileid3 fileid; filename3 name; cookie3 cookie; post_op_attr name_attributes; post_op_fh3 name_handle; entryplus3 *nextentry; }; struct dirlistplus3 { entryplus3 *entries; bool eof; }; struct READDIRPLUS3resok { post_op_attr dir_attributes; cookieverf3 cookieverf; dirlistplus3 reply; }; struct READDIRPLUS3resfail { post_op_attr dir_attributes; }; union READDIRPLUS3res switch (nfsstat3 status) { case NFS3_OK: READDIRPLUS3resok resok; default: READDIRPLUS3resfail resfail; }; struct READDIR3args { nfs_fh3 dir; cookie3 cookie; cookieverf3 cookieverf; count3 count; }; struct entry3 { fileid3 fileid; filename3 name; cookie3 cookie; entry3 *nextentry; }; struct dirlist3 { entry3 *entries; bool eof; }; struct READDIR3resok { post_op_attr dir_attributes; cookieverf3 cookieverf; dirlist3 reply; }; struct READDIR3resfail { post_op_attr dir_attributes; }; union READDIR3res switch (nfsstat3 status) { case NFS3_OK: READDIR3resok resok; default: READDIR3resfail resfail; }; struct LINK3args { nfs_fh3 file; diropargs3 link; }; struct LINK3resok { post_op_attr file_attributes; wcc_data linkdir_wcc; }; struct LINK3resfail { post_op_attr file_attributes; wcc_data linkdir_wcc; }; union LINK3res switch (nfsstat3 status) { case NFS3_OK: LINK3resok resok; default: LINK3resfail resfail; }; union sattrguard3 switch (bool check) { case TRUE: nfstime3 obj_ctime; case FALSE: void; }; struct SETATTR3args { nfs_fh3 object; sattr3 new_attributes; sattrguard3 guard; }; struct SETATTR3resok { wcc_data obj_wcc; }; struct SETATTR3resfail { wcc_data obj_wcc; }; union SETATTR3res switch (nfsstat3 status) { case NFS3_OK: SETATTR3resok resok; default: SETATTR3resfail resfail; }; /* * NFS v2 Definitions * We share many definitions from v3 */ const FHSIZE2 = 32; typedef opaque fhandle2[FHSIZE2]; enum ftype2 { NF2NON = 0, NF2REG = 1, NF2DIR = 2, NF2BLK = 3, NF2CHR = 4, NF2LNK = 5 }; struct fattr2 { ftype2 type; unsigned int mode; unsigned int nlink; unsigned int uid; unsigned int gid; unsigned int size; unsigned int blocksize; unsigned int rdev; unsigned int blocks; unsigned int fsid; unsigned int fileid; nfstime3 atime; nfstime3 mtime; nfstime3 ctime; }; struct sattr2 { unsigned int mode; unsigned int uid; unsigned int gid; unsigned int size; nfstime3 atime; nfstime3 mtime; }; const MAXNAMLEN2 = 255; typedef string filename2; const MAXPATHLEN2 = 1024; typedef string path2; const NFSMAXDATA2 = 8192; typedef opaque nfsdata2; const NFSCOOKIESIZE2 = 4; typedef opaque nfscookie2[NFSCOOKIESIZE2]; struct entry2 { unsigned int fileid; filename2 name; nfscookie2 cookie; entry2 *nextentry; }; struct diropargs2 { fhandle2 dir; filename2 name; }; struct GETATTR2args { fhandle2 fhandle; }; struct GETATTR2resok { fattr2 attributes; }; union GETATTR2res switch (nfsstat3 status) { case NFS3_OK: GETATTR2resok resok; default: void; }; struct SETATTR2args { fhandle2 fhandle; sattr2 attributes; }; struct SETATTR2resok { fattr2 attributes; }; union SETATTR2res switch (nfsstat3 status) { case NFS3_OK: SETATTR2resok resok; default: void; }; struct LOOKUP2args { diropargs2 what; }; struct LOOKUP2resok { fhandle2 file; fattr2 attributes; }; union LOOKUP2res switch (nfsstat3 status) { case NFS3_OK: LOOKUP2resok resok; default: void; }; struct READLINK2args { fhandle2 file; }; struct READLINK2resok { path2 data; }; union READLINK2res switch (nfsstat3 status) { case NFS3_OK: READLINK2resok resok; default: void; }; struct READ2args { fhandle2 file; unsigned int offset; unsigned int count; unsigned int totalcount; }; struct READ2resok { fattr2 attributes; nfsdata2 data; }; union READ2res switch (nfsstat3 status) { case NFS3_OK: READ2resok resok; default: void; }; struct WRITE2args { fhandle2 file; unsigned int beginoffset; unsigned int offset; unsigned int totalcount; nfsdata2 data; }; struct WRITE2resok { fattr2 attributes; }; union WRITE2res switch (nfsstat3 status) { case NFS3_OK: WRITE2resok resok; default: void; }; struct CREATE2args { diropargs2 where; sattr2 attributes; }; struct CREATE2resok { fhandle2 file; fattr2 attributes; }; union CREATE2res switch (nfsstat3 status) { case NFS3_OK: CREATE2resok resok; default: void; }; struct REMOVE2args { diropargs2 what; }; struct REMOVE2res { nfsstat3 status; }; struct RENAME2args { diropargs2 from; diropargs2 to; }; struct RENAME2res { nfsstat3 status; }; struct LINK2args { fhandle2 from; diropargs2 to; }; struct LINK2res { nfsstat3 status; }; struct SYMLINK2args { diropargs2 from; path2 to; sattr2 attributes; }; struct SYMLINK2res { nfsstat3 status; }; struct MKDIR2args { diropargs2 where; sattr2 attributes; }; struct MKDIR2resok { fhandle2 file; fattr2 attributes; }; union MKDIR2res switch (nfsstat3 status) { case NFS3_OK: MKDIR2resok resok; default: void; }; struct RMDIR2args { diropargs2 what; }; struct RMDIR2res { nfsstat3 status; }; struct READDIR2args { fhandle2 dir; nfscookie2 cookie; unsigned int count; }; struct READDIR2resok { entry2 *entries; bool eof; }; union READDIR2res switch (nfsstat3 status) { case NFS3_OK: READDIR2resok resok; default: void; }; struct STATFS2args { fhandle2 dir; }; struct STATFS2resok { unsigned int tsize; unsigned int bsize; unsigned int blocks; unsigned int bfree; unsigned int bavail; }; union STATFS2res switch (nfsstat3 status) { case NFS3_OK: STATFS2resok resok; default: void; }; program NFS_PROGRAM { version NFS_V2 { void NFS2_NULL(void) = 0; GETATTR2res NFS2_GETATTR(GETATTR2args) = 1; SETATTR2res NFS2_SETATTR(SETATTR2args) = 2; LOOKUP2res NFS2_LOOKUP(LOOKUP2args) = 4; READLINK2res NFS2_READLINK(READLINK2args) = 5; READ2res NFS2_READ(READ2args) = 6; WRITE2res NFS2_WRITE(WRITE2args) = 8; CREATE2res NFS2_CREATE(CREATE2args) = 9; REMOVE2res NFS2_REMOVE(REMOVE2args) = 10; RENAME2res NFS2_RENAME(RENAME2args) = 11; LINK2res NFS2_LINK(LINK2args) = 12; SYMLINK2res NFS2_SYMLINK(SYMLINK2args) = 13; MKDIR2res NFS2_MKDIR(MKDIR2args) = 14; RMDIR2res NFS2_RMDIR(RMDIR2args) = 15; READDIR2res NFS2_READDIR(READDIR2args) = 16; STATFS2res NFS2_STATFS(STATFS2args) = 17; } = 2; version NFS_V3 { void NFS3_NULL(void) = 0; GETATTR3res NFS3_GETATTR(GETATTR3args) = 1; SETATTR3res NFS3_SETATTR(SETATTR3args) = 2; LOOKUP3res NFS3_LOOKUP(LOOKUP3args) = 3; ACCESS3res NFS3_ACCESS(ACCESS3args) = 4; READLINK3res NFS3_READLINK(READLINK3args) = 5; READ3res NFS3_READ(READ3args) = 6; WRITE3res NFS3_WRITE(WRITE3args) = 7; CREATE3res NFS3_CREATE(CREATE3args) = 8; MKDIR3res NFS3_MKDIR(MKDIR3args) = 9; SYMLINK3res NFS3_SYMLINK(SYMLINK3args) = 10; MKNOD3res NFS3_MKNOD(MKNOD3args) = 11; REMOVE3res NFS3_REMOVE(REMOVE3args) = 12; RMDIR3res NFS3_RMDIR(RMDIR3args) = 13; RENAME3res NFS3_RENAME(RENAME3args) = 14; LINK3res NFS3_LINK(LINK3args) = 15; READDIR3res NFS3_READDIR(READDIR3args) = 16; READDIRPLUS3res NFS3_READDIRPLUS(READDIRPLUS3args) = 17; FSSTAT3res NFS3_FSSTAT(FSSTAT3args) = 18; FSINFO3res NFS3_FSINFO(FSINFO3args) = 19; PATHCONF3res NFS3_PATHCONF(PATHCONF3args) = 20; COMMIT3res NFS3_COMMIT(COMMIT3args) = 21; } = 3; } = 100003; /* NFS ACL definitions based on wireshark souces and network traces */ /* NFSACL interface. Uses same port/process as NFS */ enum nfsacl_type { NFSACL_TYPE_USER_OBJ = 0x0001, NFSACL_TYPE_USER = 0x0002, NFSACL_TYPE_GROUP_OBJ = 0x0004, NFSACL_TYPE_GROUP = 0x0008, NFSACL_TYPE_CLASS_OBJ = 0x0010, NFSACL_TYPE_CLASS = 0x0020, NFSACL_TYPE_DEFAULT = 0x1000, NFSACL_TYPE_DEFAULT_USER_OBJ = 0x1001, NFSACL_TYPE_DEFAULT_USER = 0x1002, NFSACL_TYPE_DEFAULT_GROUP_OBJ = 0x1004, NFSACL_TYPE_DEFAULT_GROUP = 0x1008, NFSACL_TYPE_DEFAULT_CLASS_OBJ = 0x1010, NFSACL_TYPE_DEFAULT_OTHER_OBJ = 0x1020 }; const NFSACL_PERM_READ = 0x04; const NFSACL_PERM_WRITE = 0x02; const NFSACL_PERM_EXEC = 0x01; struct nfsacl_ace { enum nfsacl_type type; unsigned int id; unsigned int perm; }; const NFSACL_MASK_ACL_ENTRY = 0x0001; const NFSACL_MASK_ACL_COUNT = 0x0002; const NFSACL_MASK_ACL_DEFAULT_ENTRY = 0x0004; const NFSACL_MASK_ACL_DEFAULT_COUNT = 0x0008; struct GETACL3args { nfs_fh3 dir; unsigned int mask; }; struct GETACL3resok { post_op_attr attr; unsigned int mask; unsigned int ace_count; struct nfsacl_ace ace<>; unsigned int default_ace_count; struct nfsacl_ace default_ace<>; }; union GETACL3res switch (nfsstat3 status) { case NFS3_OK: GETACL3resok resok; default: void; }; struct SETACL3args { nfs_fh3 dir; unsigned int mask; unsigned int ace_count; struct nfsacl_ace ace<>; unsigned int default_ace_count; struct nfsacl_ace default_ace<>; }; struct SETACL3resok { post_op_attr attr; }; union SETACL3res switch (nfsstat3 status) { case NFS3_OK: SETACL3resok resok; default: void; }; program NFSACL_PROGRAM { version NFSACL_V3 { void NFSACL3_NULL(void) = 0; GETACL3res NFSACL3_GETACL(GETACL3args) = 1; SETACL3res NFSACL3_SETACL(SETACL3args) = 2; } = 3; } = 100227; libnfs-libnfs-1.9.8/nfs/nfsacl.c000066400000000000000000000056411255745034100164750ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef WIN32 #include "win32_compat.h" #else #include #endif/*WIN32*/ #include #include #include #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" #include "libnfs-raw-nfs.h" int rpc_nfsacl_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFSACL_PROGRAM, NFSACL_V3, NFSACL3_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfsacl/null call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfsacl/null call"); rpc_free_pdu(rpc, pdu); return -2; } return 0; } int rpc_nfsacl_getacl_async(struct rpc_context *rpc, rpc_cb cb, struct GETACL3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFSACL_PROGRAM, NFSACL_V3, NFSACL3_GETACL, cb, private_data, (zdrproc_t)zdr_GETACL3res, sizeof(GETACL3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfsacl/getacl call"); return -1; } if (zdr_GETACL3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode GETACL3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfsacl/getacl call"); rpc_free_pdu(rpc, pdu); return -2; } return 0; } int rpc_nfsacl_setacl_async(struct rpc_context *rpc, rpc_cb cb, struct SETACL3args *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NFSACL_PROGRAM, NFSACL_V3, NFSACL3_SETACL, cb, private_data, (zdrproc_t)zdr_SETACL3res, sizeof(SETACL3res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nfsacl/setacl call"); return -1; } if (zdr_SETACL3args(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode SETACL3args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nfsacl/setacl call"); rpc_free_pdu(rpc, pdu); return -2; } return 0; } libnfs-libnfs-1.9.8/nlm/000077500000000000000000000000001255745034100150555ustar00rootroot00000000000000libnfs-libnfs-1.9.8/nlm/Makefile.am000066400000000000000000000020041255745034100171050ustar00rootroot00000000000000noinst_LTLIBRARIES = libnlm.la nlm_SOURCES_GENERATED = nlm_HEADERS_GENERATED = nlm_GENERATED = $(nlm_SOURCES_GENERATED) $(nlm_HEADERS_GENERATED) CLEANFILES = $(nlm_GENERATED) nlm-stamp libnlm_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc libnlm_la_SOURCES = \ $(nlm_SOURCES_GENERATED) \ nlm.c libnfs-raw-nlm.c libnfs-raw-nlm.h $(nlm_GENERATED) : nlm-stamp nlm-stamp : nlm.x rm -f $(nlm_GENERATED) touch nlm-stamp compile_rpc: cat nlm.x | head -29 >libnfs-raw-nlm.h rpcgen -h nlm.x | sed -e "s/#include /#include /" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nlm.h cat nlm.x | head -29 >libnfs-raw-nlm.c rpcgen -c nlm.x | sed -e "s/#include \".*nlm.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-nlm.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nlm.c libnfs-libnfs-1.9.8/nlm/libnfs-raw-nlm.c000066400000000000000000000143261255745034100200570ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include "libnfs-zdr.h" #include "libnfs-raw-nlm.h" uint32_t zdr_nlm_fh4 (ZDR *zdrs, nlm_fh4 *objp) { if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) return FALSE; return TRUE; } uint32_t zdr_nlm4_oh (ZDR *zdrs, nlm4_oh *objp) { if (!zdr_string (zdrs, objp, ~0)) return FALSE; return TRUE; } uint32_t zdr_nlm_cookie (ZDR *zdrs, nlm_cookie *objp) { if (!zdr_bytes (zdrs, (char **)&objp->data.data_val, (u_int *) &objp->data.data_len, ~0)) return FALSE; return TRUE; } uint32_t zdr_nlmstat4 (ZDR *zdrs, nlmstat4 *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_nlm4_holder (ZDR *zdrs, nlm4_holder *objp) { if (!zdr_bool (zdrs, &objp->exclusive)) return FALSE; if (!zdr_u_int (zdrs, &objp->svid)) return FALSE; if (!zdr_nlm4_oh (zdrs, &objp->oh)) return FALSE; if (!zdr_uint64_t (zdrs, &objp->l_offset)) return FALSE; if (!zdr_uint64_t (zdrs, &objp->l_len)) return FALSE; return TRUE; } uint32_t zdr_nlm4_lock (ZDR *zdrs, nlm4_lock *objp) { if (!zdr_string (zdrs, &objp->caller_name, NLM_MAXNAME)) return FALSE; if (!zdr_nlm_fh4 (zdrs, &objp->fh)) return FALSE; if (!zdr_nlm4_oh (zdrs, &objp->oh)) return FALSE; if (!zdr_u_int (zdrs, &objp->svid)) return FALSE; if (!zdr_uint64_t (zdrs, &objp->l_offset)) return FALSE; if (!zdr_uint64_t (zdrs, &objp->l_len)) return FALSE; return TRUE; } uint32_t zdr_nlm4_share (ZDR *zdrs, nlm4_share *objp) { if (!zdr_string (zdrs, &objp->caller_name, NLM_MAXNAME)) return FALSE; if (!zdr_nlm_fh4 (zdrs, &objp->fh)) return FALSE; if (!zdr_nlm4_oh (zdrs, &objp->oh)) return FALSE; if (!zdr_u_int (zdrs, &objp->mode)) return FALSE; if (!zdr_u_int (zdrs, &objp->access)) return FALSE; return TRUE; } uint32_t zdr_nlm4_testres_denied (ZDR *zdrs, nlm4_testres_denied *objp) { if (!zdr_nlm4_holder (zdrs, &objp->holder)) return FALSE; return TRUE; } uint32_t zdr_nlm4_testreply (ZDR *zdrs, nlm4_testreply *objp) { if (!zdr_nlmstat4 (zdrs, &objp->status)) return FALSE; switch (objp->status) { case NLM4_DENIED: if (!zdr_nlm4_testres_denied (zdrs, &objp->nlm4_testreply_u.lock)) return FALSE; break; default: break; } return TRUE; } uint32_t zdr_NLM4_TESTres (ZDR *zdrs, NLM4_TESTres *objp) { if (!zdr_nlm_cookie (zdrs, &objp->cookie)) return FALSE; if (!zdr_nlm4_testreply (zdrs, &objp->reply)) return FALSE; return TRUE; } uint32_t zdr_NLM4_TESTargs (ZDR *zdrs, NLM4_TESTargs *objp) { if (!zdr_nlm_cookie (zdrs, &objp->cookie)) return FALSE; if (!zdr_bool (zdrs, &objp->exclusive)) return FALSE; if (!zdr_nlm4_lock (zdrs, &objp->lock)) return FALSE; return TRUE; } uint32_t zdr_NLM4_CANCres (ZDR *zdrs, NLM4_CANCres *objp) { if (!zdr_nlm_cookie (zdrs, &objp->cookie)) return FALSE; if (!zdr_nlmstat4 (zdrs, &objp->status)) return FALSE; return TRUE; } uint32_t zdr_NLM4_CANCargs (ZDR *zdrs, NLM4_CANCargs *objp) { if (!zdr_nlm_cookie (zdrs, &objp->cookie)) return FALSE; if (!zdr_bool (zdrs, &objp->block)) return FALSE; if (!zdr_bool (zdrs, &objp->exclusive)) return FALSE; if (!zdr_nlm4_lock (zdrs, &objp->lock)) return FALSE; return TRUE; } uint32_t zdr_NLM4_UNLOCKres (ZDR *zdrs, NLM4_UNLOCKres *objp) { if (!zdr_nlm_cookie (zdrs, &objp->cookie)) return FALSE; if (!zdr_nlmstat4 (zdrs, &objp->status)) return FALSE; return TRUE; } uint32_t zdr_NLM4_UNLOCKargs (ZDR *zdrs, NLM4_UNLOCKargs *objp) { if (!zdr_nlm_cookie (zdrs, &objp->cookie)) return FALSE; if (!zdr_nlm4_lock (zdrs, &objp->lock)) return FALSE; return TRUE; } uint32_t zdr_NLM4_LOCKres (ZDR *zdrs, NLM4_LOCKres *objp) { if (!zdr_nlm_cookie (zdrs, &objp->cookie)) return FALSE; if (!zdr_nlmstat4 (zdrs, &objp->status)) return FALSE; return TRUE; } uint32_t zdr_NLM4_LOCKargs (ZDR *zdrs, NLM4_LOCKargs *objp) { if (!zdr_nlm_cookie (zdrs, &objp->cookie)) return FALSE; if (!zdr_bool (zdrs, &objp->block)) return FALSE; if (!zdr_bool (zdrs, &objp->exclusive)) return FALSE; if (!zdr_nlm4_lock (zdrs, &objp->lock)) return FALSE; if (!zdr_bool (zdrs, &objp->reclaim)) return FALSE; if (!zdr_int (zdrs, &objp->state)) return FALSE; return TRUE; } uint32_t zdr_NLM4_GRANTEDargs (ZDR *zdrs, NLM4_GRANTEDargs *objp) { if (!zdr_nlm_cookie (zdrs, &objp->cookie)) return FALSE; if (!zdr_bool (zdrs, &objp->exclusive)) return FALSE; if (!zdr_nlm4_lock (zdrs, &objp->lock)) return FALSE; return TRUE; } uint32_t zdr_NLM4_GRANTEDres (ZDR *zdrs, NLM4_GRANTEDres *objp) { if (!zdr_nlm_cookie (zdrs, &objp->cookie)) return FALSE; if (!zdr_nlmstat4 (zdrs, &objp->status)) return FALSE; return TRUE; } libnfs-libnfs-1.9.8/nlm/libnfs-raw-nlm.h000066400000000000000000000244461255745034100200700ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _NLM_H_RPCGEN #define _NLM_H_RPCGEN #include #ifdef __cplusplus extern "C" { #endif struct nlm_fh4 { struct { u_int data_len; char *data_val; } data; }; typedef struct nlm_fh4 nlm_fh4; typedef char *nlm4_oh; struct nlm_cookie { struct { u_int data_len; char *data_val; } data; }; typedef struct nlm_cookie nlm_cookie; enum nlmstat4 { NLM4_GRANTED = 0, NLM4_DENIED = 1, NLM4_DENIED_NOLOCKS = 2, NLM4_BLOCKED = 3, NLM4_DENIED_GRACE_PERIOD = 4, NLM4_DEADLCK = 5, NLM4_ROFS = 6, NLM4_STALE_FH = 7, NLM4_FBIG = 8, NLM4_FAILED = 9, }; typedef enum nlmstat4 nlmstat4; struct nlm4_holder { uint32_t exclusive; u_int svid; nlm4_oh oh; uint64_t l_offset; uint64_t l_len; }; typedef struct nlm4_holder nlm4_holder; #define NLM_MAXNAME 256 struct nlm4_lock { char *caller_name; struct nlm_fh4 fh; nlm4_oh oh; u_int svid; uint64_t l_offset; uint64_t l_len; }; typedef struct nlm4_lock nlm4_lock; struct nlm4_share { char *caller_name; struct nlm_fh4 fh; nlm4_oh oh; u_int mode; u_int access; }; typedef struct nlm4_share nlm4_share; struct nlm4_testres_denied { nlm4_holder holder; }; typedef struct nlm4_testres_denied nlm4_testres_denied; struct nlm4_testreply { nlmstat4 status; union { nlm4_testres_denied lock; } nlm4_testreply_u; }; typedef struct nlm4_testreply nlm4_testreply; struct NLM4_TESTres { nlm_cookie cookie; nlm4_testreply reply; }; typedef struct NLM4_TESTres NLM4_TESTres; struct NLM4_TESTargs { nlm_cookie cookie; uint32_t exclusive; nlm4_lock lock; }; typedef struct NLM4_TESTargs NLM4_TESTargs; struct NLM4_CANCres { nlm_cookie cookie; nlmstat4 status; }; typedef struct NLM4_CANCres NLM4_CANCres; struct NLM4_CANCargs { nlm_cookie cookie; uint32_t block; uint32_t exclusive; nlm4_lock lock; }; typedef struct NLM4_CANCargs NLM4_CANCargs; struct NLM4_UNLOCKres { nlm_cookie cookie; nlmstat4 status; }; typedef struct NLM4_UNLOCKres NLM4_UNLOCKres; struct NLM4_UNLOCKargs { nlm_cookie cookie; nlm4_lock lock; }; typedef struct NLM4_UNLOCKargs NLM4_UNLOCKargs; struct NLM4_LOCKres { nlm_cookie cookie; nlmstat4 status; }; typedef struct NLM4_LOCKres NLM4_LOCKres; struct NLM4_LOCKargs { nlm_cookie cookie; uint32_t block; uint32_t exclusive; nlm4_lock lock; uint32_t reclaim; int state; }; typedef struct NLM4_LOCKargs NLM4_LOCKargs; struct NLM4_GRANTEDargs { nlm_cookie cookie; uint32_t exclusive; nlm4_lock lock; }; typedef struct NLM4_GRANTEDargs NLM4_GRANTEDargs; struct NLM4_GRANTEDres { nlm_cookie cookie; nlmstat4 status; }; typedef struct NLM4_GRANTEDres NLM4_GRANTEDres; #define NLM_PROGRAM 100021 #define NLM_V4 4 #if defined(__STDC__) || defined(__cplusplus) #define NLM4_NULL 0 extern void * nlm4_null_4(void *, void *); extern void * nlm4_null_4_svc(void *, struct svc_req *); #define NLM4_TEST 1 extern NLM4_TESTres * nlm4_test_4(NLM4_TESTargs *, void *); extern NLM4_TESTres * nlm4_test_4_svc(NLM4_TESTargs *, struct svc_req *); #define NLM4_LOCK 2 extern NLM4_LOCKres * nlm4_lock_4(NLM4_LOCKargs *, void *); extern NLM4_LOCKres * nlm4_lock_4_svc(NLM4_LOCKargs *, struct svc_req *); #define NLM4_CANCEL 3 extern NLM4_CANCres * nlm4_cancel_4(NLM4_CANCargs *, void *); extern NLM4_CANCres * nlm4_cancel_4_svc(NLM4_CANCargs *, struct svc_req *); #define NLM4_UNLOCK 4 extern NLM4_UNLOCKres * nlm4_unlock_4(NLM4_UNLOCKargs *, void *); extern NLM4_UNLOCKres * nlm4_unlock_4_svc(NLM4_UNLOCKargs *, struct svc_req *); #define NLM4_GRANT 5 extern NLM4_GRANTEDres * nlm4_grant_4(NLM4_GRANTEDargs *, void *); extern NLM4_GRANTEDres * nlm4_grant_4_svc(NLM4_GRANTEDargs *, struct svc_req *); #define NLM4_TEST_MSG 6 extern void * nlm4_test_msg_4(NLM4_TESTargs *, void *); extern void * nlm4_test_msg_4_svc(NLM4_TESTargs *, struct svc_req *); #define NLM4_LOCK_MSG 7 extern void * nlm4_lock_msg_4(NLM4_LOCKargs *, void *); extern void * nlm4_lock_msg_4_svc(NLM4_LOCKargs *, struct svc_req *); #define NLM4_CANCEL_MSG 8 extern void * nlm4_cancel_msg_4(NLM4_CANCargs *, void *); extern void * nlm4_cancel_msg_4_svc(NLM4_CANCargs *, struct svc_req *); #define NLM4_UNLOCK_MSG 9 extern void * nlm4_unlock_msg_4(NLM4_UNLOCKargs *, void *); extern void * nlm4_unlock_msg_4_svc(NLM4_UNLOCKargs *, struct svc_req *); #define NLM4_GRANT_MSG 10 extern void * nlm4_grant_msg_4(NLM4_GRANTEDargs *, void *); extern void * nlm4_grant_msg_4_svc(NLM4_GRANTEDargs *, struct svc_req *); #define NLM4_TEST_RES 11 extern void * nlm4_test_res_4(NLM4_TESTres *, void *); extern void * nlm4_test_res_4_svc(NLM4_TESTres *, struct svc_req *); #define NLM4_LOCK_RES 12 extern void * nlm4_lock_res_4(NLM4_LOCKres *, void *); extern void * nlm4_lock_res_4_svc(NLM4_LOCKres *, struct svc_req *); #define NLM4_CANCEL_RES 13 extern void * nlm4_cancel_res_4(NLM4_CANCres *, void *); extern void * nlm4_cancel_res_4_svc(NLM4_CANCres *, struct svc_req *); #define NLM4_UNLOCK_RES 14 extern void * nlm4_unlock_res_4(NLM4_UNLOCKres *, void *); extern void * nlm4_unlock_res_4_svc(NLM4_UNLOCKres *, struct svc_req *); #define NLM4_GRANT_RES 15 extern void * nlm4_grant_res_4(NLM4_GRANTEDres *, void *); extern void * nlm4_grant_res_4_svc(NLM4_GRANTEDres *, struct svc_req *); extern int nlm_program_4_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define NLM4_NULL 0 extern void * nlm4_null_4(); extern void * nlm4_null_4_svc(); #define NLM4_TEST 1 extern NLM4_TESTres * nlm4_test_4(); extern NLM4_TESTres * nlm4_test_4_svc(); #define NLM4_LOCK 2 extern NLM4_LOCKres * nlm4_lock_4(); extern NLM4_LOCKres * nlm4_lock_4_svc(); #define NLM4_CANCEL 3 extern NLM4_CANCres * nlm4_cancel_4(); extern NLM4_CANCres * nlm4_cancel_4_svc(); #define NLM4_UNLOCK 4 extern NLM4_UNLOCKres * nlm4_unlock_4(); extern NLM4_UNLOCKres * nlm4_unlock_4_svc(); #define NLM4_GRANT 5 extern NLM4_GRANTEDres * nlm4_grant_4(); extern NLM4_GRANTEDres * nlm4_grant_4_svc(); #define NLM4_TEST_MSG 6 extern void * nlm4_test_msg_4(); extern void * nlm4_test_msg_4_svc(); #define NLM4_LOCK_MSG 7 extern void * nlm4_lock_msg_4(); extern void * nlm4_lock_msg_4_svc(); #define NLM4_CANCEL_MSG 8 extern void * nlm4_cancel_msg_4(); extern void * nlm4_cancel_msg_4_svc(); #define NLM4_UNLOCK_MSG 9 extern void * nlm4_unlock_msg_4(); extern void * nlm4_unlock_msg_4_svc(); #define NLM4_GRANT_MSG 10 extern void * nlm4_grant_msg_4(); extern void * nlm4_grant_msg_4_svc(); #define NLM4_TEST_RES 11 extern void * nlm4_test_res_4(); extern void * nlm4_test_res_4_svc(); #define NLM4_LOCK_RES 12 extern void * nlm4_lock_res_4(); extern void * nlm4_lock_res_4_svc(); #define NLM4_CANCEL_RES 13 extern void * nlm4_cancel_res_4(); extern void * nlm4_cancel_res_4_svc(); #define NLM4_UNLOCK_RES 14 extern void * nlm4_unlock_res_4(); extern void * nlm4_unlock_res_4_svc(); #define NLM4_GRANT_RES 15 extern void * nlm4_grant_res_4(); extern void * nlm4_grant_res_4_svc(); extern int nlm_program_4_freeresult (); #endif /* K&R C */ /* the zdr functions */ #if defined(__STDC__) || defined(__cplusplus) extern uint32_t zdr_nlm_fh4 (ZDR *, nlm_fh4*); extern uint32_t zdr_nlm4_oh (ZDR *, nlm4_oh*); extern uint32_t zdr_nlm_cookie (ZDR *, nlm_cookie*); extern uint32_t zdr_nlmstat4 (ZDR *, nlmstat4*); extern uint32_t zdr_nlm4_holder (ZDR *, nlm4_holder*); extern uint32_t zdr_nlm4_lock (ZDR *, nlm4_lock*); extern uint32_t zdr_nlm4_share (ZDR *, nlm4_share*); extern uint32_t zdr_nlm4_testres_denied (ZDR *, nlm4_testres_denied*); extern uint32_t zdr_nlm4_testreply (ZDR *, nlm4_testreply*); extern uint32_t zdr_NLM4_TESTres (ZDR *, NLM4_TESTres*); extern uint32_t zdr_NLM4_TESTargs (ZDR *, NLM4_TESTargs*); extern uint32_t zdr_NLM4_CANCres (ZDR *, NLM4_CANCres*); extern uint32_t zdr_NLM4_CANCargs (ZDR *, NLM4_CANCargs*); extern uint32_t zdr_NLM4_UNLOCKres (ZDR *, NLM4_UNLOCKres*); extern uint32_t zdr_NLM4_UNLOCKargs (ZDR *, NLM4_UNLOCKargs*); extern uint32_t zdr_NLM4_LOCKres (ZDR *, NLM4_LOCKres*); extern uint32_t zdr_NLM4_LOCKargs (ZDR *, NLM4_LOCKargs*); extern uint32_t zdr_NLM4_GRANTEDargs (ZDR *, NLM4_GRANTEDargs*); extern uint32_t zdr_NLM4_GRANTEDres (ZDR *, NLM4_GRANTEDres*); #else /* K&R C */ extern uint32_t zdr_nlm_fh4 (); extern uint32_t zdr_nlm4_oh (); extern uint32_t zdr_nlm_cookie (); extern uint32_t zdr_nlmstat4 (); extern uint32_t zdr_nlm4_holder (); extern uint32_t zdr_nlm4_lock (); extern uint32_t zdr_nlm4_share (); extern uint32_t zdr_nlm4_testres_denied (); extern uint32_t zdr_nlm4_testreply (); extern uint32_t zdr_NLM4_TESTres (); extern uint32_t zdr_NLM4_TESTargs (); extern uint32_t zdr_NLM4_CANCres (); extern uint32_t zdr_NLM4_CANCargs (); extern uint32_t zdr_NLM4_UNLOCKres (); extern uint32_t zdr_NLM4_UNLOCKargs (); extern uint32_t zdr_NLM4_LOCKres (); extern uint32_t zdr_NLM4_LOCKargs (); extern uint32_t zdr_NLM4_GRANTEDargs (); extern uint32_t zdr_NLM4_GRANTEDres (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_NLM_H_RPCGEN */ libnfs-libnfs-1.9.8/nlm/nlm.c000066400000000000000000000115231255745034100160110ustar00rootroot00000000000000/* Copyright (C) 2012 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef WIN32 #include "win32_compat.h" #endif/*WIN32*/ #include #include #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" #include "libnfs-raw-nlm.h" int rpc_nlm4_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/null call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/null call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_nlm4_test_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_TESTargs *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_TEST, cb, private_data, (zdrproc_t)zdr_NLM4_TESTres, sizeof(NLM4_TESTres)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/test call"); return -1; } if (zdr_NLM4_TESTargs(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode NLM4_TESTargs"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/test call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_nlm4_lock_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_LOCKargs *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_LOCK, cb, private_data, (zdrproc_t)zdr_NLM4_LOCKres, sizeof(NLM4_LOCKres)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/lock call"); return -1; } if (zdr_NLM4_LOCKargs(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode NLM4_LOCKargs"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/lock call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_nlm4_cancel_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_CANCargs *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_CANCEL, cb, private_data, (zdrproc_t)zdr_NLM4_CANCres, sizeof(NLM4_CANCres)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/cancel call"); return -1; } if (zdr_NLM4_CANCargs(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode NLM4_CANCargs"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/cancel call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_nlm4_unlock_async(struct rpc_context *rpc, rpc_cb cb, struct NLM4_UNLOCKargs *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NLM_PROGRAM, NLM_V4, NLM4_UNLOCK, cb, private_data, (zdrproc_t)zdr_NLM4_UNLOCKres, sizeof(NLM4_UNLOCKres)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nlm/unlock call"); return -1; } if (zdr_NLM4_UNLOCKargs(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode NLM4_UNLOCKargs"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nlm/unlock call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } char *nlmstat4_to_str(int st) { enum nlmstat4 stat = st; char *str = "unknown nlm stat"; switch (stat) { case NLM4_GRANTED: str="NLM4_GRANTED";break; case NLM4_DENIED: str="NLM4_DENIED";break; case NLM4_DENIED_NOLOCKS: str="NLM4_DENIED_NOLOCKS";break; case NLM4_BLOCKED: str="NLM4_BLOCKED";break; case NLM4_DENIED_GRACE_PERIOD: str="NLM4_DENIED_GRACE_PERIOD";break; case NLM4_DEADLCK: str="NLM4_DEADLCK";break; case NLM4_ROFS: str="NLM4_ROFS";break; case NLM4_STALE_FH: str="NLM4_STALE_FH";break; case NLM4_FBIG: str="NLM4_FBIG";break; case NLM4_FAILED: str="NLM4_FAILED";break; } return str; } libnfs-libnfs-1.9.8/nlm/nlm.x000066400000000000000000000105761255745034100160450ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ struct nlm_fh4 { opaque data<>; }; typedef string nlm4_oh<>; struct nlm_cookie { opaque data<>; }; enum nlmstat4 { NLM4_GRANTED = 0, NLM4_DENIED = 1, NLM4_DENIED_NOLOCKS = 2, NLM4_BLOCKED = 3, NLM4_DENIED_GRACE_PERIOD = 4, NLM4_DEADLCK = 5, NLM4_ROFS = 6, NLM4_STALE_FH = 7, NLM4_FBIG = 8, NLM4_FAILED = 9 }; struct nlm4_holder { bool exclusive; unsigned int svid; nlm4_oh oh; uint64_t l_offset; uint64_t l_len; }; const NLM_MAXNAME = 256; struct nlm4_lock { string caller_name; struct nlm_fh4 fh; nlm4_oh oh; unsigned int svid; uint64_t l_offset; uint64_t l_len; }; struct nlm4_share { string caller_name; struct nlm_fh4 fh; nlm4_oh oh; unsigned int mode; unsigned int access; }; struct nlm4_testres_denied { nlm4_holder holder; }; union nlm4_testreply switch (nlmstat4 status) { case NLM4_DENIED: nlm4_testres_denied lock; default: void; }; struct NLM4_TESTres { nlm_cookie cookie; nlm4_testreply reply; }; struct NLM4_TESTargs { nlm_cookie cookie; bool exclusive; nlm4_lock lock; }; struct NLM4_CANCres { nlm_cookie cookie; nlmstat4 status; }; struct NLM4_CANCargs { nlm_cookie cookie; bool block; bool exclusive; nlm4_lock lock; }; struct NLM4_UNLOCKres { nlm_cookie cookie; nlmstat4 status; }; struct NLM4_UNLOCKargs { nlm_cookie cookie; nlm4_lock lock; }; struct NLM4_LOCKres { nlm_cookie cookie; nlmstat4 status; }; struct NLM4_LOCKargs { nlm_cookie cookie; bool block; bool exclusive; nlm4_lock lock; bool reclaim; int state; }; struct NLM4_GRANTEDargs { nlm_cookie cookie; bool exclusive; nlm4_lock lock; }; struct NLM4_GRANTEDres { nlm_cookie cookie; nlmstat4 status; }; program NLM_PROGRAM { version NLM_V4 { void NLM4_NULL(void) = 0; NLM4_TESTres NLM4_TEST(NLM4_TESTargs) = 1; NLM4_LOCKres NLM4_LOCK(NLM4_LOCKargs) = 2; NLM4_CANCres NLM4_CANCEL(NLM4_CANCargs) = 3; NLM4_UNLOCKres NLM4_UNLOCK(NLM4_UNLOCKargs) = 4; NLM4_GRANTEDres NLM4_GRANT(NLM4_GRANTEDargs) = 5; void NLM4_TEST_MSG(NLM4_TESTargs) = 6; void NLM4_LOCK_MSG(NLM4_LOCKargs) = 7; void NLM4_CANCEL_MSG(NLM4_CANCargs) = 8; void NLM4_UNLOCK_MSG(NLM4_UNLOCKargs) = 9; void NLM4_GRANT_MSG(NLM4_GRANTEDargs) = 10; void NLM4_TEST_RES(NLM4_TESTres) = 11; void NLM4_LOCK_RES(NLM4_LOCKres) = 12; void NLM4_CANCEL_RES(NLM4_CANCres) = 13; void NLM4_UNLOCK_RES(NLM4_UNLOCKres) = 14; void NLM4_GRANT_RES(NLM4_GRANTEDres) = 15; /* nlm4_shareres */ /* NLM4_SHARE(nlm4_shareargs) = 20; */ /* nlm4_shareres */ /* NLM4_UNSHARE(nlm4_shareargs) = 21; */ /* nlm4_res */ /* NLM4_NM_LOCK(nlm4_lockargs) = 22; */ /* void */ /* NLM4_FREE_ALL(nlm4_notify) = 23; */ } = 4; } = 100021; libnfs-libnfs-1.9.8/nsm/000077500000000000000000000000001255745034100150645ustar00rootroot00000000000000libnfs-libnfs-1.9.8/nsm/Makefile.am000066400000000000000000000020041255745034100171140ustar00rootroot00000000000000noinst_LTLIBRARIES = libnsm.la nsm_SOURCES_GENERATED = nsm_HEADERS_GENERATED = nsm_GENERATED = $(nsm_SOURCES_GENERATED) $(nsm_HEADERS_GENERATED) CLEANFILES = $(nsm_GENERATED) nsm-stamp libnsm_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc libnsm_la_SOURCES = \ $(nsm_SOURCES_GENERATED) \ nsm.c libnfs-raw-nsm.c libnfs-raw-nsm.h $(nsm_GENERATED) : nsm-stamp nsm-stamp : nsm.x rm -f $(nsm_GENERATED) touch nsm-stamp compile_rpc: cat nsm.x | head -29 >libnfs-raw-nsm.h rpcgen -h nsm.x | sed -e "s/#include /#include /" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nsm.h cat nsm.x | head -29 >libnfs-raw-nsm.c rpcgen -c nsm.x | sed -e "s/#include \".*nsm.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-nsm.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-nsm.c libnfs-libnfs-1.9.8/nsm/libnfs-raw-nsm.c000066400000000000000000000073251255745034100200760ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include "libnfs-zdr.h" #include "libnfs-raw-nsm.h" uint32_t zdr_nsmstat1 (ZDR *zdrs, nsmstat1 *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_nsm_my_id (ZDR *zdrs, nsm_my_id *objp) { if (!zdr_string (zdrs, &objp->my_name, NSM_MAXSTRLEN)) return FALSE; if (!zdr_int (zdrs, &objp->my_prog)) return FALSE; if (!zdr_int (zdrs, &objp->my_vers)) return FALSE; if (!zdr_int (zdrs, &objp->my_proc)) return FALSE; return TRUE; } uint32_t zdr_nsm_mon_id (ZDR *zdrs, nsm_mon_id *objp) { if (!zdr_string (zdrs, &objp->mon_name, NSM_MAXSTRLEN)) return FALSE; if (!zdr_nsm_my_id (zdrs, &objp->my_id)) return FALSE; return TRUE; } uint32_t zdr_NSM1_STATres (ZDR *zdrs, NSM1_STATres *objp) { if (!zdr_nsmstat1 (zdrs, &objp->res)) return FALSE; if (!zdr_int (zdrs, &objp->state)) return FALSE; return TRUE; } uint32_t zdr_NSM1_STATargs (ZDR *zdrs, NSM1_STATargs *objp) { if (!zdr_string (zdrs, &objp->mon_name, NSM_MAXSTRLEN)) return FALSE; return TRUE; } uint32_t zdr_NSM1_MONres (ZDR *zdrs, NSM1_MONres *objp) { if (!zdr_nsmstat1 (zdrs, &objp->res)) return FALSE; if (!zdr_int (zdrs, &objp->state)) return FALSE; return TRUE; } uint32_t zdr_NSM1_MONargs (ZDR *zdrs, NSM1_MONargs *objp) { if (!zdr_nsm_mon_id (zdrs, &objp->mon_id)) return FALSE; if (!zdr_opaque (zdrs, objp->priv, 16)) return FALSE; return TRUE; } uint32_t zdr_NSM1_UNMONres (ZDR *zdrs, NSM1_UNMONres *objp) { if (!zdr_int (zdrs, &objp->state)) return FALSE; return TRUE; } uint32_t zdr_NSM1_UNMONargs (ZDR *zdrs, NSM1_UNMONargs *objp) { if (!zdr_nsm_mon_id (zdrs, &objp->mon_id)) return FALSE; return TRUE; } uint32_t zdr_NSM1_UNMONALLres (ZDR *zdrs, NSM1_UNMONALLres *objp) { if (!zdr_int (zdrs, &objp->state)) return FALSE; return TRUE; } uint32_t zdr_NSM1_UNMONALLargs (ZDR *zdrs, NSM1_UNMONALLargs *objp) { if (!zdr_nsm_my_id (zdrs, &objp->my_id)) return FALSE; return TRUE; } uint32_t zdr_NSM1_NOTIFYargs (ZDR *zdrs, NSM1_NOTIFYargs *objp) { if (!zdr_string (zdrs, &objp->mon_name, NSM_MAXSTRLEN)) return FALSE; if (!zdr_int (zdrs, &objp->state)) return FALSE; return TRUE; } libnfs-libnfs-1.9.8/nsm/libnfs-raw-nsm.h000066400000000000000000000144521255745034100201020ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _NSM_H_RPCGEN #define _NSM_H_RPCGEN #include #ifdef __cplusplus extern "C" { #endif #define NSM_MAXSTRLEN 1024 enum nsmstat1 { NSM_STAT_SUCC = 0, NSM_STAT_FAIL = 1, }; typedef enum nsmstat1 nsmstat1; struct nsm_my_id { char *my_name; int my_prog; int my_vers; int my_proc; }; typedef struct nsm_my_id nsm_my_id; struct nsm_mon_id { char *mon_name; struct nsm_my_id my_id; }; typedef struct nsm_mon_id nsm_mon_id; struct NSM1_STATres { nsmstat1 res; int state; }; typedef struct NSM1_STATres NSM1_STATres; struct NSM1_STATargs { char *mon_name; }; typedef struct NSM1_STATargs NSM1_STATargs; struct NSM1_MONres { nsmstat1 res; int state; }; typedef struct NSM1_MONres NSM1_MONres; struct NSM1_MONargs { struct nsm_mon_id mon_id; char priv[16]; }; typedef struct NSM1_MONargs NSM1_MONargs; struct NSM1_UNMONres { int state; }; typedef struct NSM1_UNMONres NSM1_UNMONres; struct NSM1_UNMONargs { struct nsm_mon_id mon_id; }; typedef struct NSM1_UNMONargs NSM1_UNMONargs; struct NSM1_UNMONALLres { int state; }; typedef struct NSM1_UNMONALLres NSM1_UNMONALLres; struct NSM1_UNMONALLargs { struct nsm_my_id my_id; }; typedef struct NSM1_UNMONALLargs NSM1_UNMONALLargs; struct NSM1_NOTIFYargs { char *mon_name; int state; }; typedef struct NSM1_NOTIFYargs NSM1_NOTIFYargs; #define NSM_PROGRAM 100024 #define NSM_V1 1 #if defined(__STDC__) || defined(__cplusplus) #define NSM1_NULL 0 extern void * nsm1_null_1(void *, void *); extern void * nsm1_null_1_svc(void *, struct svc_req *); #define NSM1_STAT 1 extern struct NSM1_STATres * nsm1_stat_1(struct NSM1_STATargs *, void *); extern struct NSM1_STATres * nsm1_stat_1_svc(struct NSM1_STATargs *, struct svc_req *); #define NSM1_MON 2 extern struct NSM1_MONres * nsm1_mon_1(struct NSM1_MONargs *, void *); extern struct NSM1_MONres * nsm1_mon_1_svc(struct NSM1_MONargs *, struct svc_req *); #define NSM1_UNMON 3 extern struct NSM1_UNMONres * nsm1_unmon_1(struct NSM1_UNMONargs *, void *); extern struct NSM1_UNMONres * nsm1_unmon_1_svc(struct NSM1_UNMONargs *, struct svc_req *); #define NSM1_UNMON_ALL 4 extern struct NSM1_UNMONALLres * nsm1_unmon_all_1(struct NSM1_UNMONALLargs *, void *); extern struct NSM1_UNMONALLres * nsm1_unmon_all_1_svc(struct NSM1_UNMONALLargs *, struct svc_req *); #define NSM1_SIMU_CRASH 5 extern void * nsm1_simu_crash_1(void *, void *); extern void * nsm1_simu_crash_1_svc(void *, struct svc_req *); #define NSM1_NOTIFY 6 extern void * nsm1_notify_1(struct NSM1_NOTIFYargs *, void *); extern void * nsm1_notify_1_svc(struct NSM1_NOTIFYargs *, struct svc_req *); extern int nsm_program_1_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define NSM1_NULL 0 extern void * nsm1_null_1(); extern void * nsm1_null_1_svc(); #define NSM1_STAT 1 extern struct NSM1_STATres * nsm1_stat_1(); extern struct NSM1_STATres * nsm1_stat_1_svc(); #define NSM1_MON 2 extern struct NSM1_MONres * nsm1_mon_1(); extern struct NSM1_MONres * nsm1_mon_1_svc(); #define NSM1_UNMON 3 extern struct NSM1_UNMONres * nsm1_unmon_1(); extern struct NSM1_UNMONres * nsm1_unmon_1_svc(); #define NSM1_UNMON_ALL 4 extern struct NSM1_UNMONALLres * nsm1_unmon_all_1(); extern struct NSM1_UNMONALLres * nsm1_unmon_all_1_svc(); #define NSM1_SIMU_CRASH 5 extern void * nsm1_simu_crash_1(); extern void * nsm1_simu_crash_1_svc(); #define NSM1_NOTIFY 6 extern void * nsm1_notify_1(); extern void * nsm1_notify_1_svc(); extern int nsm_program_1_freeresult (); #endif /* K&R C */ /* the zdr functions */ #if defined(__STDC__) || defined(__cplusplus) extern uint32_t zdr_nsmstat1 (ZDR *, nsmstat1*); extern uint32_t zdr_nsm_my_id (ZDR *, nsm_my_id*); extern uint32_t zdr_nsm_mon_id (ZDR *, nsm_mon_id*); extern uint32_t zdr_NSM1_STATres (ZDR *, NSM1_STATres*); extern uint32_t zdr_NSM1_STATargs (ZDR *, NSM1_STATargs*); extern uint32_t zdr_NSM1_MONres (ZDR *, NSM1_MONres*); extern uint32_t zdr_NSM1_MONargs (ZDR *, NSM1_MONargs*); extern uint32_t zdr_NSM1_UNMONres (ZDR *, NSM1_UNMONres*); extern uint32_t zdr_NSM1_UNMONargs (ZDR *, NSM1_UNMONargs*); extern uint32_t zdr_NSM1_UNMONALLres (ZDR *, NSM1_UNMONALLres*); extern uint32_t zdr_NSM1_UNMONALLargs (ZDR *, NSM1_UNMONALLargs*); extern uint32_t zdr_NSM1_NOTIFYargs (ZDR *, NSM1_NOTIFYargs*); #else /* K&R C */ extern uint32_t zdr_nsmstat1 (); extern uint32_t zdr_nsm_my_id (); extern uint32_t zdr_nsm_mon_id (); extern uint32_t zdr_NSM1_STATres (); extern uint32_t zdr_NSM1_STATargs (); extern uint32_t zdr_NSM1_MONres (); extern uint32_t zdr_NSM1_MONargs (); extern uint32_t zdr_NSM1_UNMONres (); extern uint32_t zdr_NSM1_UNMONargs (); extern uint32_t zdr_NSM1_UNMONALLres (); extern uint32_t zdr_NSM1_UNMONALLargs (); extern uint32_t zdr_NSM1_NOTIFYargs (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_NSM_H_RPCGEN */ libnfs-libnfs-1.9.8/nsm/nsm.c000066400000000000000000000132311255745034100160250ustar00rootroot00000000000000/* Copyright (C) 2013 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef WIN32 #include "win32_compat.h" #endif/*WIN32*/ #include #include #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" #include "libnfs-raw-nsm.h" int rpc_nsm1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/null call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/null call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_nsm1_stat_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_STATargs *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_STAT, cb, private_data, (zdrproc_t)zdr_NSM1_STATres, sizeof(NSM1_STATres)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/stat call"); return -1; } if (zdr_NSM1_STATargs(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode NSM1_STATargs"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/stat call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_nsm1_mon_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_MONargs *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_MON, cb, private_data, (zdrproc_t)zdr_NSM1_MONres, sizeof(NSM1_MONres)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/mon call"); return -1; } if (zdr_NSM1_MONargs(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode NSM1_MONargs"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/mon call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_nsm1_unmon_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_UNMONargs *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_UNMON, cb, private_data, (zdrproc_t)zdr_NSM1_UNMONres, sizeof(NSM1_UNMONres)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/unmon call"); return -1; } if (zdr_NSM1_UNMONargs(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode NSM1_UNMONargs"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/unmon call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_nsm1_unmonall_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_UNMONALLargs *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_UNMON_ALL, cb, private_data, (zdrproc_t)zdr_NSM1_UNMONALLres, sizeof(NSM1_UNMONALLres)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/unmonall call"); return -1; } if (zdr_NSM1_UNMONALLargs(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode NSM1_UNMONALLargs"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/unmonall call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_nsm1_simucrash_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_SIMU_CRASH, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/simucrash call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/simucrash call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_nsm1_notify_async(struct rpc_context *rpc, rpc_cb cb, struct NSM1_NOTIFYargs *args, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, NSM_PROGRAM, NSM_V1, NSM1_NOTIFY, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for nsm/notify call"); return -1; } if (zdr_NSM1_NOTIFYargs(&pdu->zdr, args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode NSM1_NOTIFYargs"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for nsm/notify call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } char *nsmstat1_to_str(int st) { enum nsmstat1 stat = st; char *str = "unknown n1m stat"; switch (stat) { case NSM_STAT_SUCC: str="NSM_STAT_SUCC";break; case NSM_STAT_FAIL: str="NSM_STAT_FAIL";break; } return str; } libnfs-libnfs-1.9.8/nsm/nsm.x000066400000000000000000000064011255745034100160530ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * This defines the maximum length of the string * identifying the caller. */ const NSM_MAXSTRLEN = 1024; enum nsmstat1 { NSM_STAT_SUCC = 0, /* NSM agrees to monitor. */ NSM_STAT_FAIL = 1 /* NSM cannot monitor. */ }; struct nsm_my_id { string my_name; /* hostname */ int my_prog; /* RPC program number */ int my_vers; /* program version number */ int my_proc; /* procedure number */ }; struct nsm_mon_id { string mon_name; /* name of the host to be monitored */ struct nsm_my_id my_id; }; struct NSM1_STATres { nsmstat1 res; int state; }; struct NSM1_STATargs { string mon_name; }; struct NSM1_MONres { nsmstat1 res; int state; }; struct NSM1_MONargs { struct nsm_mon_id mon_id; opaque priv[16]; /* private information */ }; struct NSM1_UNMONres { int state; /* state number of NSM */ }; struct NSM1_UNMONargs { struct nsm_mon_id mon_id; }; struct NSM1_UNMONALLres { int state; /* state number of NSM */ }; struct NSM1_UNMONALLargs { struct nsm_my_id my_id; }; struct NSM1_NOTIFYargs { string mon_name; int state; }; /* * Protocol description for the NSM program. */ program NSM_PROGRAM { version NSM_V1 { void NSM1_NULL(void) = 0; struct NSM1_STATres NSM1_STAT(struct NSM1_STATargs) = 1; struct NSM1_MONres NSM1_MON(struct NSM1_MONargs) = 2; struct NSM1_UNMONres NSM1_UNMON(struct NSM1_UNMONargs) = 3; struct NSM1_UNMONALLres NSM1_UNMON_ALL(struct NSM1_UNMONALLargs) = 4; void NSM1_SIMU_CRASH(void) = 5; void NSM1_NOTIFY(struct NSM1_NOTIFYargs) = 6; } = 1; } = 100024; libnfs-libnfs-1.9.8/packaging/000077500000000000000000000000001255745034100162135ustar00rootroot00000000000000libnfs-libnfs-1.9.8/packaging/RPM/000077500000000000000000000000001255745034100166515ustar00rootroot00000000000000libnfs-libnfs-1.9.8/packaging/RPM/libnfs.spec.in000066400000000000000000000151531255745034100214140ustar00rootroot00000000000000Name: libnfs Summary: NFS client library Vendor: Ronnie Sahlberg Packager: ronniesahlberg@gmail.com Version: @VERSION@ Release: 1 Epoch: 0 License: GNU LGPL version 2.1 Group: System Environment/Libraries URL: http://www.github.com/sahlberg/libnfs Source: libnfs-%{version}.tar.gz Provides: lib = %{version} Prefix: /usr BuildRoot: %{_tmppath}/%{name}-%{version}-root %description LibNFS is a NFS client library ####################################################################### %prep %setup -q # setup the init script and sysconfig file %setup -T -D -n libnfs-%{version} -q %build ## check for ccache if ccache -h >/dev/null 2>&1 ; then CC="ccache gcc" else CC="gcc" fi export CC ## always run autogen.sh aclocal autoheader autoconf libtoolize -c -f -i automake --add-missing CFLAGS="$RPM_OPT_FLAGS $EXTRA -O0 -g -D_GNU_SOURCE" %configure %install # Clean up in case there is trash left from a previous build rm -rf $RPM_BUILD_ROOT # Create the target build directory hierarchy make DESTDIR=$RPM_BUILD_ROOT install # Remove "*.old" files find $RPM_BUILD_ROOT -name "*.old" -exec rm -f {} \; %clean rm -rf $RPM_BUILD_ROOT ####################################################################### ## Files section ## ####################################################################### %files %defattr(-,root,root) %{_libdir}/libnfs.so* %package devel Summary: Development libraries for LibNFS Group: Development %description devel development libraries for LibNFS %files devel %defattr(-,root,root) %{_includedir}/nfsc/libnfs.h %{_includedir}/nfsc/libnfs-zdr.h %{_includedir}/nfsc/libnfs-raw.h %{_includedir}/nfsc/libnfs-raw-mount.h %{_includedir}/nfsc/libnfs-raw-nfs.h %{_includedir}/nfsc/libnfs-raw-portmap.h %{_includedir}/nfsc/libnfs-raw-rquota.h %{_includedir}/nfsc/libnfs-raw-nlm.h %{_includedir}/nfsc/libnfs-raw-nsm.h %{_libdir}/libnfs.a %{_libdir}/libnfs.la %{_libdir}/pkgconfig/libnfs.pc %package utils Summary: Utility programs for LibNFS Group: Applications/System %description utils Utility programs for LibNFS %files utils %defattr(-,root,root) %{_bindir}/nfs-cat %{_bindir}/nfs-cp %{_bindir}/nfs-ls %{_mandir}/man1/nfs-cat.1.gz %{_mandir}/man1/nfs-cp.1.gz %{_mandir}/man1/nfs-ls.1.gz %changelog * Sun Aug 2 2015 : Version 1.9.8 - Disable multithreading in fuse_nfs - Add -Wall and -Werror compiler flags (and fix issues found by it) - Add nfs-cat utility - Switch to using nfs_[f]stat64 instead of the deprecated nfs_[f]stat call in all examples - If the server does not return any atttributes for entries in READDIRPLUS then try to fetch them using lookup instead. - Reconnection fixes - Enforce the max pdu size and add sanity checks when reading PDUs from the socket. - Stop using ioctl(FIONREAD) to find out how many bytes to read, and treat 0 as an indication of a problem. Some applications call their POLLIN handlers spuriosly even when there is no data to read, which breaks this check in libnfs. - Add basic support to do logging. * Mon Feb 9 2015 : Version 1.9.7 - Auto-traverse mounts. With this option (default to on) libnfs will autodiscover and handle any nested submounts. - Remove nfs_get_current_offset. Applications should use seek instead of this function. - Add umask() support. - Change set_tcp_sockopt() to be static. - Android fix for nfs-ls - Make S_IFLNK available on windows. - Fix a use after free. - Fix a bug where truncate() treated offset as 32bit. * Tue Nov 25 2014 : Version 1.9.6 - Add O_TRUNC support for nfs_create - Handle OOM during create - Return more stats fields as part of readdir since we get these for "free" when we use READDIRPLUS - Follow symlinks during path resolution - Add lchown, lstat and lutimes - Replace all [u_]quad types with [u]int types in our RPC layer - Solaris build fixes * Sat Jul 19 2014 : Version 1.9.5 - Remove old ONC-RPC symbols * Wed Mar 19 2014 : Version 1.9.3 - Add O_TRUNC support to nfs_open() - Add a simple but incomplete LD_PRELOAD tool - Fixes for some memory leaks and C++ compile support - Make ANDROID default uid/gid to 65534 - Allow the READDIRPLUS emulation to still work if some objects in the direcotry can not be lookedup (NFSv4 ACL denying READ-ATTRIBUTES) - Have libnfs retry any read/write operations where the server responds with a short read/write. Some servers do this when they are overloaded? * Thu Jan 30 2014 : Version 1.9.2 - Remove chdir change. This needs more testing. * Tue Jan 28 2014 : Version 1.9.1 - Restore libnfs-raw-*.h to make install * Mon Jan 27 2014 : Version 1.9 - Use _stat64 on windows so file sizes become 64bit always. - Increase default marshalling buffer so we can marshall large PDUs. - RPC layer support for NFSv2 - Win32 updates and fixes - Add URL parsing functions and URL argument support. - New utility: nfs-io - nfs-ls enhancements - RPC layer support for NSM - Add example FUSE filesystem. - Minor fixes. * Wed Oct 30 2013 : Version 1.8 - Fix nasty memory leak in read_from_socket - minor updates * Sun Oct 20 2013 : Version 1.7 - Allow nested eventloops so that a sync function can be called from a callback. - Fix a bug in unmarshalling a uint64. - Add PATHCONF support. - WIN32/64 updates - AROS updates * Mon May 27 2013 : Version 1.6 - AROS/Amiga support - Chose better initial xid value to reduce the probability for collissions. - Set default group to getgid() instead of -1. This fixes an interoperability problem with 3.9 linux knfsd. * Mon Dec 3 2012 : Version 1.5 - Switch to using our own RPC/XDR replacement ZDR instead of relying on the system RPC/TIRPC libraries. This allows using libnfs on platforms that lack RPC libraries completely. - Add support for Android. * Sun Nov 25 2012 : Version 1.4 - Add trackig of freed context and assert on using a context after it has been freed. - Windows x64 support and fixes. - Switch to using our own version of xdr_int64() since the one in libtirpc crashes on some platforms. - Fix memory leak in an error path for addrinfo. - Fix bug dereferencing a null pointer in the mount callback on error. * Sat Mar 3 2012 : Version 1.3 - add set/unset to portmapper - add mount v1 - try to rotate to find a free port better - minor fixes * Tue Dec 6 2011 : Version 1.2 - Add support for MKNOD - Add support for HaneWin NFS server - Change all [s]size_t offset_t to be 64bit clean scalars * Sun Nov 27 2011 : Version 1.1 - Fix definition and use of AUTH - Only call the "connect" callback if non-NULL - make sure the callback for connect is only invoked once for the sync api - make file offset bits 64 bits always * Sun Jul 31 2011 : Version 1.0 - Initial version libnfs-libnfs-1.9.8/packaging/RPM/makerpms.sh000077500000000000000000000056431255745034100210370ustar00rootroot00000000000000#!/bin/sh # # makerpms.sh - build RPM packages from the git sources # # Copyright (C) John H Terpstra 1998-2002 # Copyright (C) Gerald (Jerry) Carter 2003 # Copyright (C) Jim McDonough 2007 # Copyright (C) Andrew Tridgell 2007 # Copyright (C) Michael Adam 2008-2009 # # 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 . # # # The following allows environment variables to override the target directories # the alternative is to have a file in your home directory calles .rpmmacros # containing the following: # %_topdir /home/mylogin/redhat # # Note: Under this directory rpm expects to find the same directories that are under the # /usr/src/redhat directory # EXTRA_OPTIONS="$1" DIRNAME=$(dirname $0) TOPDIR=${DIRNAME}/../.. SPECDIR=`rpm --eval %_specdir` SRCDIR=`rpm --eval %_sourcedir` SPECFILE="libnfs.spec" SPECFILE_IN="libnfs.spec.in" RPMBUILD="rpmbuild" # We use tags and determine the version, as follows: # libnfs-0.9.1 (First release of 0.9). # libnfs-0.9.23 (23rd minor release of the 112 version) # # If we're not directly on a tag, this is a devel release; we append # .0...devel to the release. TAG=`git describe` case "$TAG" in libnfs-*) TAG=${TAG##libnfs-} case "$TAG" in *-*-g*) # 0.9-168-ge6cf0e8 # Not exactly on tag: devel version. VERSION=`echo "$TAG" | sed 's/\([^-]\+\)-\([0-9]\+\)-\(g[0-9a-f]\+\)/\1.0.\2.\3.devel/'` ;; *) # An actual release version VERSION=$TAG ;; esac ;; *) echo Invalid tag "$TAG" >&2 exit 1 ;; esac sed -e s/@VERSION@/$VERSION/g \ < ${DIRNAME}/${SPECFILE_IN} \ > ${DIRNAME}/${SPECFILE} VERSION=$(grep ^Version ${DIRNAME}/${SPECFILE} | sed -e 's/^Version:\ \+//') if echo | gzip -c --rsyncable - > /dev/null 2>&1 ; then GZIP="gzip -9 --rsyncable" else GZIP="gzip -9" fi pushd ${TOPDIR} echo -n "Creating libnfs-${VERSION}.tar.gz ... " git archive --prefix=libnfs-${VERSION}/ HEAD | ${GZIP} > ${SRCDIR}/libnfs-${VERSION}.tar.gz RC=$? popd echo "Done." if [ $RC -ne 0 ]; then echo "Build failed!" exit 1 fi # At this point the SPECDIR and SRCDIR vaiables must have a value! ## ## copy additional source files ## cp -p ${DIRNAME}/${SPECFILE} ${SPECDIR} ## ## Build ## echo "$(basename $0): Getting Ready to build release package" ${RPMBUILD} -ba --clean --rmsource ${EXTRA_OPTIONS} ${SPECDIR}/${SPECFILE} || exit 1 echo "$(basename $0): Done." exit 0 libnfs-libnfs-1.9.8/portmap/000077500000000000000000000000001255745034100157515ustar00rootroot00000000000000libnfs-libnfs-1.9.8/portmap/Makefile.am000066400000000000000000000021711255745034100200060ustar00rootroot00000000000000noinst_LTLIBRARIES = libportmap.la portmap_SOURCES_GENERATED = portmap_HEADERS_GENERATED = portmap_GENERATED = $(portmap_SOURCES_GENERATED) $(portmap_HEADERS_GENERATED) CLEANFILES = $(portmap_GENERATED) portmap-stamp libportmap_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc libportmap_la_SOURCES = \ $(portmap_SOURCES_GENERATED) \ portmap.c libnfs-raw-portmap.c libnfs-raw-portmap.h $(portmap_GENERATED) : portmap-stamp portmap-stamp : portmap.x rm -f $(portmap_GENERATED) touch portmap-stamp compile_rpc: cat portmap.x | head -29 >libnfs-raw-portmap.h rpcgen -h portmap.x | sed -e "s/#include /#include /" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" >> libnfs-raw-portmap.h cat portmap.x | head -29 >libnfs-raw-portmap.c rpcgen -c portmap.x | sed -e "s/#include \".*portmap.h\"/#include \"libnfs-zdr.h\"\n#include \"libnfs-raw-portmap.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-portmap.c libnfs-libnfs-1.9.8/portmap/libnfs-raw-portmap.c000066400000000000000000000200641255745034100216430ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include "libnfs-zdr.h" #include "libnfs-raw-portmap.h" uint32_t zdr_pmap2_mapping (ZDR *zdrs, pmap2_mapping *objp) { register int32_t *buf; buf = NULL; if (zdrs->x_op == ZDR_ENCODE) { buf = ZDR_INLINE (zdrs, 4 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->prog)) return FALSE; if (!zdr_u_int (zdrs, &objp->vers)) return FALSE; if (!zdr_u_int (zdrs, &objp->prot)) return FALSE; if (!zdr_u_int (zdrs, &objp->port)) return FALSE; } else { IZDR_PUT_U_LONG(buf, objp->prog); IZDR_PUT_U_LONG(buf, objp->vers); IZDR_PUT_U_LONG(buf, objp->prot); IZDR_PUT_U_LONG(buf, objp->port); } return TRUE; } else if (zdrs->x_op == ZDR_DECODE) { buf = ZDR_INLINE (zdrs, 4 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->prog)) return FALSE; if (!zdr_u_int (zdrs, &objp->vers)) return FALSE; if (!zdr_u_int (zdrs, &objp->prot)) return FALSE; if (!zdr_u_int (zdrs, &objp->port)) return FALSE; } else { objp->prog = IZDR_GET_U_LONG(buf); objp->vers = IZDR_GET_U_LONG(buf); objp->prot = IZDR_GET_U_LONG(buf); objp->port = IZDR_GET_U_LONG(buf); } return TRUE; } if (!zdr_u_int (zdrs, &objp->prog)) return FALSE; if (!zdr_u_int (zdrs, &objp->vers)) return FALSE; if (!zdr_u_int (zdrs, &objp->prot)) return FALSE; if (!zdr_u_int (zdrs, &objp->port)) return FALSE; return TRUE; } uint32_t zdr_pmap2_call_args (ZDR *zdrs, pmap2_call_args *objp) { register int32_t *buf; buf = NULL; if (zdrs->x_op == ZDR_ENCODE) { buf = ZDR_INLINE (zdrs, 3 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->prog)) return FALSE; if (!zdr_u_int (zdrs, &objp->vers)) return FALSE; if (!zdr_u_int (zdrs, &objp->proc)) return FALSE; } else { IZDR_PUT_U_LONG(buf, objp->prog); IZDR_PUT_U_LONG(buf, objp->vers); IZDR_PUT_U_LONG(buf, objp->proc); } if (!zdr_bytes (zdrs, (char **)&objp->args.args_val, (u_int *) &objp->args.args_len, ~0)) return FALSE; return TRUE; } else if (zdrs->x_op == ZDR_DECODE) { buf = ZDR_INLINE (zdrs, 3 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->prog)) return FALSE; if (!zdr_u_int (zdrs, &objp->vers)) return FALSE; if (!zdr_u_int (zdrs, &objp->proc)) return FALSE; } else { objp->prog = IZDR_GET_U_LONG(buf); objp->vers = IZDR_GET_U_LONG(buf); objp->proc = IZDR_GET_U_LONG(buf); } if (!zdr_bytes (zdrs, (char **)&objp->args.args_val, (u_int *) &objp->args.args_len, ~0)) return FALSE; return TRUE; } if (!zdr_u_int (zdrs, &objp->prog)) return FALSE; if (!zdr_u_int (zdrs, &objp->vers)) return FALSE; if (!zdr_u_int (zdrs, &objp->proc)) return FALSE; if (!zdr_bytes (zdrs, (char **)&objp->args.args_val, (u_int *) &objp->args.args_len, ~0)) return FALSE; return TRUE; } uint32_t zdr_pmap2_call_result (ZDR *zdrs, pmap2_call_result *objp) { if (!zdr_u_int (zdrs, &objp->port)) return FALSE; if (!zdr_bytes (zdrs, (char **)&objp->res.res_val, (u_int *) &objp->res.res_len, ~0)) return FALSE; return TRUE; } uint32_t zdr_pmap2_mapping_list (ZDR *zdrs, pmap2_mapping_list *objp) { if (!zdr_pmap2_mapping (zdrs, &objp->map)) return FALSE; if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (pmap2_mapping_list), (zdrproc_t) zdr_pmap2_mapping_list)) return FALSE; return TRUE; } uint32_t zdr_pmap2_dump_result (ZDR *zdrs, pmap2_dump_result *objp) { if (!zdr_pointer (zdrs, (char **)&objp->list, sizeof (pmap2_mapping_list), (zdrproc_t) zdr_pmap2_mapping_list)) return FALSE; return TRUE; } uint32_t zdr_pmap3_string_result (ZDR *zdrs, pmap3_string_result *objp) { if (!zdr_string (zdrs, &objp->addr, ~0)) return FALSE; return TRUE; } uint32_t zdr_pmap3_mapping (ZDR *zdrs, pmap3_mapping *objp) { if (!zdr_u_int (zdrs, &objp->prog)) return FALSE; if (!zdr_u_int (zdrs, &objp->vers)) return FALSE; if (!zdr_string (zdrs, &objp->netid, ~0)) return FALSE; if (!zdr_string (zdrs, &objp->addr, ~0)) return FALSE; if (!zdr_string (zdrs, &objp->owner, ~0)) return FALSE; return TRUE; } uint32_t zdr_pmap3_mapping_list (ZDR *zdrs, pmap3_mapping_list *objp) { if (!zdr_pmap3_mapping (zdrs, &objp->map)) return FALSE; if (!zdr_pointer (zdrs, (char **)&objp->next, sizeof (pmap3_mapping_list), (zdrproc_t) zdr_pmap3_mapping_list)) return FALSE; return TRUE; } uint32_t zdr_pmap3_dump_result (ZDR *zdrs, pmap3_dump_result *objp) { if (!zdr_pointer (zdrs, (char **)&objp->list, sizeof (pmap3_mapping_list), (zdrproc_t) zdr_pmap3_mapping_list)) return FALSE; return TRUE; } uint32_t zdr_pmap3_call_args (ZDR *zdrs, pmap3_call_args *objp) { register int32_t *buf; buf = NULL; if (zdrs->x_op == ZDR_ENCODE) { buf = ZDR_INLINE (zdrs, 3 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->prog)) return FALSE; if (!zdr_u_int (zdrs, &objp->vers)) return FALSE; if (!zdr_u_int (zdrs, &objp->proc)) return FALSE; } else { IZDR_PUT_U_LONG(buf, objp->prog); IZDR_PUT_U_LONG(buf, objp->vers); IZDR_PUT_U_LONG(buf, objp->proc); } if (!zdr_bytes (zdrs, (char **)&objp->args.args_val, (u_int *) &objp->args.args_len, ~0)) return FALSE; return TRUE; } else if (zdrs->x_op == ZDR_DECODE) { buf = ZDR_INLINE (zdrs, 3 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_u_int (zdrs, &objp->prog)) return FALSE; if (!zdr_u_int (zdrs, &objp->vers)) return FALSE; if (!zdr_u_int (zdrs, &objp->proc)) return FALSE; } else { objp->prog = IZDR_GET_U_LONG(buf); objp->vers = IZDR_GET_U_LONG(buf); objp->proc = IZDR_GET_U_LONG(buf); } if (!zdr_bytes (zdrs, (char **)&objp->args.args_val, (u_int *) &objp->args.args_len, ~0)) return FALSE; return TRUE; } if (!zdr_u_int (zdrs, &objp->prog)) return FALSE; if (!zdr_u_int (zdrs, &objp->vers)) return FALSE; if (!zdr_u_int (zdrs, &objp->proc)) return FALSE; if (!zdr_bytes (zdrs, (char **)&objp->args.args_val, (u_int *) &objp->args.args_len, ~0)) return FALSE; return TRUE; } uint32_t zdr_pmap3_call_result (ZDR *zdrs, pmap3_call_result *objp) { if (!zdr_u_int (zdrs, &objp->port)) return FALSE; if (!zdr_bytes (zdrs, (char **)&objp->res.res_val, (u_int *) &objp->res.res_len, ~0)) return FALSE; return TRUE; } uint32_t zdr_pmap3_netbuf (ZDR *zdrs, pmap3_netbuf *objp) { if (!zdr_u_int (zdrs, &objp->maxlen)) return FALSE; if (!zdr_bytes (zdrs, (char **)&objp->buf.buf_val, (u_int *) &objp->buf.buf_len, ~0)) return FALSE; return TRUE; } libnfs-libnfs-1.9.8/portmap/libnfs-raw-portmap.h000066400000000000000000000220701255745034100216470ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _PORTMAP_H_RPCGEN #define _PORTMAP_H_RPCGEN #include #ifdef __cplusplus extern "C" { #endif #define PMAP_PORT 111 struct pmap2_mapping { u_int prog; u_int vers; u_int prot; u_int port; }; typedef struct pmap2_mapping pmap2_mapping; struct pmap2_call_args { u_int prog; u_int vers; u_int proc; struct { u_int args_len; char *args_val; } args; }; typedef struct pmap2_call_args pmap2_call_args; struct pmap2_call_result { u_int port; struct { u_int res_len; char *res_val; } res; }; typedef struct pmap2_call_result pmap2_call_result; struct pmap2_mapping_list { pmap2_mapping map; struct pmap2_mapping_list *next; }; typedef struct pmap2_mapping_list pmap2_mapping_list; struct pmap2_dump_result { struct pmap2_mapping_list *list; }; typedef struct pmap2_dump_result pmap2_dump_result; struct pmap3_string_result { char *addr; }; typedef struct pmap3_string_result pmap3_string_result; struct pmap3_mapping { u_int prog; u_int vers; char *netid; char *addr; char *owner; }; typedef struct pmap3_mapping pmap3_mapping; struct pmap3_mapping_list { pmap3_mapping map; struct pmap3_mapping_list *next; }; typedef struct pmap3_mapping_list pmap3_mapping_list; struct pmap3_dump_result { struct pmap3_mapping_list *list; }; typedef struct pmap3_dump_result pmap3_dump_result; struct pmap3_call_args { u_int prog; u_int vers; u_int proc; struct { u_int args_len; char *args_val; } args; }; typedef struct pmap3_call_args pmap3_call_args; struct pmap3_call_result { u_int port; struct { u_int res_len; char *res_val; } res; }; typedef struct pmap3_call_result pmap3_call_result; struct pmap3_netbuf { u_int maxlen; struct { u_int buf_len; char *buf_val; } buf; }; typedef struct pmap3_netbuf pmap3_netbuf; #define PMAP_PROGRAM 100000 #define PMAP_V2 2 #if defined(__STDC__) || defined(__cplusplus) #define PMAP2_NULL 0 extern void * pmap2_null_2(void *, void *); extern void * pmap2_null_2_svc(void *, struct svc_req *); #define PMAP2_SET 1 extern uint32_t * pmap2_set_2(pmap2_mapping *, void *); extern uint32_t * pmap2_set_2_svc(pmap2_mapping *, struct svc_req *); #define PMAP2_UNSET 2 extern uint32_t * pmap2_unset_2(pmap2_mapping *, void *); extern uint32_t * pmap2_unset_2_svc(pmap2_mapping *, struct svc_req *); #define PMAP2_GETPORT 3 extern u_int * pmap2_getport_2(pmap2_mapping *, void *); extern u_int * pmap2_getport_2_svc(pmap2_mapping *, struct svc_req *); #define PMAP2_DUMP 4 extern pmap2_dump_result * pmap2_dump_2(void *, void *); extern pmap2_dump_result * pmap2_dump_2_svc(void *, struct svc_req *); #define PMAP2_CALLIT 5 extern pmap2_call_result * pmap2_callit_2(pmap2_call_args *, void *); extern pmap2_call_result * pmap2_callit_2_svc(pmap2_call_args *, struct svc_req *); extern int pmap_program_2_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define PMAP2_NULL 0 extern void * pmap2_null_2(); extern void * pmap2_null_2_svc(); #define PMAP2_SET 1 extern uint32_t * pmap2_set_2(); extern uint32_t * pmap2_set_2_svc(); #define PMAP2_UNSET 2 extern uint32_t * pmap2_unset_2(); extern uint32_t * pmap2_unset_2_svc(); #define PMAP2_GETPORT 3 extern u_int * pmap2_getport_2(); extern u_int * pmap2_getport_2_svc(); #define PMAP2_DUMP 4 extern pmap2_dump_result * pmap2_dump_2(); extern pmap2_dump_result * pmap2_dump_2_svc(); #define PMAP2_CALLIT 5 extern pmap2_call_result * pmap2_callit_2(); extern pmap2_call_result * pmap2_callit_2_svc(); extern int pmap_program_2_freeresult (); #endif /* K&R C */ #define PMAP_V3 3 #if defined(__STDC__) || defined(__cplusplus) #define PMAP3_NULL 0 extern void * pmap3_null_3(void *, void *); extern void * pmap3_null_3_svc(void *, struct svc_req *); #define PMAP3_SET 1 extern uint32_t * pmap3_set_3(pmap3_mapping *, void *); extern uint32_t * pmap3_set_3_svc(pmap3_mapping *, struct svc_req *); #define PMAP3_UNSET 2 extern uint32_t * pmap3_unset_3(pmap3_mapping *, void *); extern uint32_t * pmap3_unset_3_svc(pmap3_mapping *, struct svc_req *); #define PMAP3_GETADDR 3 extern pmap3_string_result * pmap3_getaddr_3(pmap3_mapping *, void *); extern pmap3_string_result * pmap3_getaddr_3_svc(pmap3_mapping *, struct svc_req *); #define PMAP3_DUMP 4 extern pmap3_dump_result * pmap3_dump_3(void *, void *); extern pmap3_dump_result * pmap3_dump_3_svc(void *, struct svc_req *); #define PMAP3_CALLIT 5 extern pmap3_call_result * pmap3_callit_3(pmap3_call_args *, void *); extern pmap3_call_result * pmap3_callit_3_svc(pmap3_call_args *, struct svc_req *); #define PMAP3_GETTIME 6 extern u_int * pmap3_gettime_3(void *, void *); extern u_int * pmap3_gettime_3_svc(void *, struct svc_req *); #define PMAP3_UADDR2TADDR 7 extern pmap3_netbuf * pmap3_uaddr2taddr_3(char **, void *); extern pmap3_netbuf * pmap3_uaddr2taddr_3_svc(char **, struct svc_req *); #define PMAP3_TADDR2UADDR 8 extern struct pmap3_string_result * pmap3_taddr2uaddr_3(pmap3_netbuf *, void *); extern struct pmap3_string_result * pmap3_taddr2uaddr_3_svc(pmap3_netbuf *, struct svc_req *); extern int pmap_program_3_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define PMAP3_NULL 0 extern void * pmap3_null_3(); extern void * pmap3_null_3_svc(); #define PMAP3_SET 1 extern uint32_t * pmap3_set_3(); extern uint32_t * pmap3_set_3_svc(); #define PMAP3_UNSET 2 extern uint32_t * pmap3_unset_3(); extern uint32_t * pmap3_unset_3_svc(); #define PMAP3_GETADDR 3 extern pmap3_string_result * pmap3_getaddr_3(); extern pmap3_string_result * pmap3_getaddr_3_svc(); #define PMAP3_DUMP 4 extern pmap3_dump_result * pmap3_dump_3(); extern pmap3_dump_result * pmap3_dump_3_svc(); #define PMAP3_CALLIT 5 extern pmap3_call_result * pmap3_callit_3(); extern pmap3_call_result * pmap3_callit_3_svc(); #define PMAP3_GETTIME 6 extern u_int * pmap3_gettime_3(); extern u_int * pmap3_gettime_3_svc(); #define PMAP3_UADDR2TADDR 7 extern pmap3_netbuf * pmap3_uaddr2taddr_3(); extern pmap3_netbuf * pmap3_uaddr2taddr_3_svc(); #define PMAP3_TADDR2UADDR 8 extern struct pmap3_string_result * pmap3_taddr2uaddr_3(); extern struct pmap3_string_result * pmap3_taddr2uaddr_3_svc(); extern int pmap_program_3_freeresult (); #endif /* K&R C */ /* the zdr functions */ #if defined(__STDC__) || defined(__cplusplus) extern uint32_t zdr_pmap2_mapping (ZDR *, pmap2_mapping*); extern uint32_t zdr_pmap2_call_args (ZDR *, pmap2_call_args*); extern uint32_t zdr_pmap2_call_result (ZDR *, pmap2_call_result*); extern uint32_t zdr_pmap2_mapping_list (ZDR *, pmap2_mapping_list*); extern uint32_t zdr_pmap2_dump_result (ZDR *, pmap2_dump_result*); extern uint32_t zdr_pmap3_string_result (ZDR *, pmap3_string_result*); extern uint32_t zdr_pmap3_mapping (ZDR *, pmap3_mapping*); extern uint32_t zdr_pmap3_mapping_list (ZDR *, pmap3_mapping_list*); extern uint32_t zdr_pmap3_dump_result (ZDR *, pmap3_dump_result*); extern uint32_t zdr_pmap3_call_args (ZDR *, pmap3_call_args*); extern uint32_t zdr_pmap3_call_result (ZDR *, pmap3_call_result*); extern uint32_t zdr_pmap3_netbuf (ZDR *, pmap3_netbuf*); #else /* K&R C */ extern uint32_t zdr_pmap2_mapping (); extern uint32_t zdr_pmap2_call_args (); extern uint32_t zdr_pmap2_call_result (); extern uint32_t zdr_pmap2_mapping_list (); extern uint32_t zdr_pmap2_dump_result (); extern uint32_t zdr_pmap3_string_result (); extern uint32_t zdr_pmap3_mapping (); extern uint32_t zdr_pmap3_mapping_list (); extern uint32_t zdr_pmap3_dump_result (); extern uint32_t zdr_pmap3_call_args (); extern uint32_t zdr_pmap3_call_result (); extern uint32_t zdr_pmap3_netbuf (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_PORTMAP_H_RPCGEN */ libnfs-libnfs-1.9.8/portmap/portmap.c000066400000000000000000000263771255745034100176160ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef WIN32 #include "win32_compat.h" #endif/*WIN32*/ #include #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" #include "libnfs-raw-portmap.h" /* * PORTMAP v2 */ int rpc_pmap2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/NULL call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for PORTMAP2/NULL call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap2_getport_async(struct rpc_context *rpc, int program, int version, int protocol, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; struct pmap2_mapping m; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_GETPORT, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/GETPORT call"); return -1; } m.prog = program; m.vers = version; m.prot = protocol; m.port = 0; if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/GETPORT call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP2/GETPORT pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap2_set_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; struct pmap2_mapping m; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_SET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/SET call"); return -1; } m.prog = program; m.vers = version; m.prot = protocol; m.port = port; if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/SET call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP2/SET pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap2_unset_async(struct rpc_context *rpc, int program, int version, int protocol, int port, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; struct pmap2_mapping m; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_UNSET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/UNSET call"); return -1; } m.prog = program; m.vers = version; m.prot = protocol; m.port = port; if (zdr_pmap2_mapping(&pdu->zdr, &m) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/UNSET call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP2/UNSET pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap2_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_DUMP, cb, private_data, (zdrproc_t)zdr_pmap2_dump_result, sizeof(pmap2_dump_result)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/DUMP call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP2/DUMP pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap2_callit_async(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; struct pmap2_call_args ca; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V2, PMAP2_CALLIT, cb, private_data, (zdrproc_t)zdr_pmap2_call_result, sizeof(pmap2_call_result)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP2/CALLIT call"); return -1; } ca.prog = program; ca.vers = version; ca.proc = procedure; ca.args.args_len = datalen; ca.args.args_val = data; if (zdr_pmap2_call_args(&pdu->zdr, &ca) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP2/CALLIT call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP2/CALLIT pdu: %s", rpc_get_error(rpc)); return -1; } return 0; } /* * PORTMAP v3 */ int rpc_pmap3_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/NULL call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for PORTMAP3/NULL call"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap3_set_async(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_SET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/SET call"); return -1; } if (zdr_pmap3_mapping(&pdu->zdr, map) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/SET call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP3/SET pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap3_unset_async(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_UNSET, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/UNSET call"); return -1; } if (zdr_pmap3_mapping(&pdu->zdr, map) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/UNSET call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP3/UNSET pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap3_getaddr_async(struct rpc_context *rpc, struct pmap3_mapping *map, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_GETADDR, cb, private_data, (zdrproc_t)zdr_pmap3_string_result, sizeof(pmap3_string_result)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/GETADDR call"); return -1; } if (zdr_pmap3_mapping(&pdu->zdr, map) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/GETADDR call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP3/GETADDR pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap3_dump_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_DUMP, cb, private_data, (zdrproc_t)zdr_pmap3_dump_result, sizeof(pmap3_dump_result)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/DUMP call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP3/DUMP pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap3_gettime_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_GETTIME, cb, private_data, (zdrproc_t)zdr_int, sizeof(uint32_t)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/GETTIME call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP3/GETTIME pdu"); rpc_free_pdu(rpc, pdu); return -1; } return 0; } int rpc_pmap3_callit_async(struct rpc_context *rpc, int program, int version, int procedure, char *data, int datalen, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; struct pmap3_call_args ca; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_CALLIT, cb, private_data, (zdrproc_t)zdr_pmap3_call_result, sizeof(pmap3_call_result)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/CALLIT call"); return -1; } ca.prog = program; ca.vers = version; ca.proc = procedure; ca.args.args_len = datalen; ca.args.args_val = data; if (zdr_pmap3_call_args(&pdu->zdr, &ca) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/CALLIT call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP3/CALLIT pdu: %s", rpc_get_error(rpc)); return -1; } return 0; } int rpc_pmap3_uaddr2taddr_async(struct rpc_context *rpc, char *uaddr, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_UADDR2TADDR, cb, private_data, (zdrproc_t)zdr_pmap3_netbuf, sizeof(pmap3_netbuf)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/UADDR2TADDR call"); return -1; } if (zdr_string(&pdu->zdr, &uaddr, 255) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/UADDR2TADDR call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP3/UADDR2TADDR pdu: %s", rpc_get_error(rpc)); return -1; } return 0; } int rpc_pmap3_taddr2uaddr_async(struct rpc_context *rpc, struct pmap3_netbuf *nb, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, PMAP_PROGRAM, PMAP_V3, PMAP3_TADDR2UADDR, cb, private_data, (zdrproc_t)zdr_pmap3_string_result, sizeof(pmap3_string_result)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for PORTMAP3/TADDR2UADDR call"); return -1; } if (zdr_pmap3_netbuf(&pdu->zdr, nb) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode data for PORTMAP3/TADDR2UADDR call"); rpc_free_pdu(rpc, pdu); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Failed to queue PORTMAP3/TADDR2UADDR pdu: %s", rpc_get_error(rpc)); return -1; } return 0; } libnfs-libnfs-1.9.8/portmap/portmap.x000066400000000000000000000073131255745034100176300ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ const PMAP_PORT = 111; /* portmapper port number */ struct pmap2_mapping { unsigned int prog; unsigned int vers; unsigned int prot; unsigned int port; }; struct pmap2_call_args { unsigned int prog; unsigned int vers; unsigned int proc; opaque args<>; }; struct pmap2_call_result { unsigned int port; opaque res<>; }; struct pmap2_mapping_list { pmap2_mapping map; pmap2_mapping_list *next; }; struct pmap2_dump_result { struct pmap2_mapping_list *list; }; struct pmap3_string_result { string addr<>; }; struct pmap3_mapping { unsigned int prog; unsigned int vers; string netid<>; string addr<>; string owner<>; }; struct pmap3_mapping_list { pmap3_mapping map; pmap3_mapping_list *next; }; struct pmap3_dump_result { struct pmap3_mapping_list *list; }; struct pmap3_call_args { unsigned int prog; unsigned int vers; unsigned int proc; opaque args<>; }; struct pmap3_call_result { unsigned int port; opaque res<>; }; struct pmap3_netbuf { unsigned int maxlen; /* This pretty much contains a sockaddr_storage. * Beware differences in endianess for ss_family * and whether or not ss_len exists. */ opaque buf<>; }; program PMAP_PROGRAM { version PMAP_V2 { void PMAP2_NULL(void) = 0; bool PMAP2_SET(pmap2_mapping) = 1; bool PMAP2_UNSET(pmap2_mapping) = 2; unsigned int PMAP2_GETPORT(pmap2_mapping) = 3; pmap2_dump_result PMAP2_DUMP(void) = 4; pmap2_call_result PMAP2_CALLIT(pmap2_call_args) = 5; } = 2; version PMAP_V3 { void PMAP3_NULL(void) = 0; bool PMAP3_SET(pmap3_mapping) = 1; bool PMAP3_UNSET(pmap3_mapping) = 2; pmap3_string_result PMAP3_GETADDR(pmap3_mapping) = 3; pmap3_dump_result PMAP3_DUMP(void) = 4; pmap3_call_result PMAP3_CALLIT(pmap3_call_args) = 5; unsigned int PMAP3_GETTIME(void) = 6; pmap3_netbuf PMAP3_UADDR2TADDR(string) = 7; struct pmap3_string_result PMAP3_TADDR2UADDR(pmap3_netbuf) = 8; } = 3; } = 100000; libnfs-libnfs-1.9.8/rquota/000077500000000000000000000000001255745034100156025ustar00rootroot00000000000000libnfs-libnfs-1.9.8/rquota/Makefile.am000066400000000000000000000021311255745034100176330ustar00rootroot00000000000000noinst_LTLIBRARIES = librquota.la rquota_SOURCES_GENERATED = rquota_HEADERS_GENERATED = rquota_GENERATED = $(rquota_SOURCES_GENERATED) $(rquota_HEADERS_GENERATED) CLEANFILES = $(rquota_GENERATED) rquota-stamp librquota_la_CPPFLAGS = -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc librquota_la_SOURCES = \ $(rquota_SOURCES_GENERATED) \ rquota.c libnfs-raw-rquota.c libnfs-raw-rquota.h $(rquota_GENERATED) : rquota-stamp rquota-stamp : rquota.x rm -f $(rquota_GENERATED) touch rquota-stamp compile_rpc: cat rquota.x | head -29 >libnfs-raw-rquota.h rpcgen -h rquota.x | sed -e "s/#include /#include /" | sed -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/ CLIENT / void /g" -e "s/SVCXPRT /void /g" -e "s/bool_t/uint32_t/g" >> libnfs-raw-rquota.h cat rquota.x | head -29 >libnfs-raw-rquota.c rpcgen -c rquota.x | sed -e "s/#include \".*rquota.h\"/#include \"libnfs-xdr.h\"\n#include \"libnfs-raw-rquota.h\"/" -e "s/xdr/zdr/g" -e "s/XDR/ZDR/g" -e "s/register int32_t \*buf;/register int32_t *buf;\n buf = NULL;/" -e "s/bool_t/uint32_t/g" >> libnfs-raw-rquota.c libnfs-libnfs-1.9.8/rquota/libnfs-raw-rquota.c000066400000000000000000000132531255745034100213270ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #include "libnfs-zdr.h" #include "libnfs-raw-rquota.h" uint32_t zdr_rquotastat (ZDR *zdrs, rquotastat *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_exportpath (ZDR *zdrs, exportpath *objp) { if (!zdr_string (zdrs, objp, RQUOTAPATHLEN)) return FALSE; return TRUE; } uint32_t zdr_GETQUOTA1args (ZDR *zdrs, GETQUOTA1args *objp) { if (!zdr_exportpath (zdrs, &objp->export)) return FALSE; if (!zdr_int (zdrs, &objp->uid)) return FALSE; return TRUE; } uint32_t zdr_quotatype (ZDR *zdrs, quotatype *objp) { if (!zdr_enum (zdrs, (enum_t *) objp)) return FALSE; return TRUE; } uint32_t zdr_GETQUOTA2args (ZDR *zdrs, GETQUOTA2args *objp) { if (!zdr_exportpath (zdrs, &objp->export)) return FALSE; if (!zdr_quotatype (zdrs, &objp->type)) return FALSE; if (!zdr_int (zdrs, &objp->uid)) return FALSE; return TRUE; } uint32_t zdr_GETQUOTA1res_ok (ZDR *zdrs, GETQUOTA1res_ok *objp) { register int32_t *buf; buf = NULL; if (zdrs->x_op == ZDR_ENCODE) { buf = ZDR_INLINE (zdrs, 10 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_int (zdrs, &objp->bsize)) return FALSE; if (!zdr_int (zdrs, &objp->active)) return FALSE; if (!zdr_int (zdrs, &objp->bhardlimit)) return FALSE; if (!zdr_int (zdrs, &objp->bsoftlimit)) return FALSE; if (!zdr_int (zdrs, &objp->curblocks)) return FALSE; if (!zdr_int (zdrs, &objp->fhardlimit)) return FALSE; if (!zdr_int (zdrs, &objp->fsoftlimit)) return FALSE; if (!zdr_int (zdrs, &objp->curfiles)) return FALSE; if (!zdr_int (zdrs, &objp->btimeleft)) return FALSE; if (!zdr_int (zdrs, &objp->ftimeleft)) return FALSE; } else { IZDR_PUT_LONG(buf, objp->bsize); IZDR_PUT_LONG(buf, objp->active); IZDR_PUT_LONG(buf, objp->bhardlimit); IZDR_PUT_LONG(buf, objp->bsoftlimit); IZDR_PUT_LONG(buf, objp->curblocks); IZDR_PUT_LONG(buf, objp->fhardlimit); IZDR_PUT_LONG(buf, objp->fsoftlimit); IZDR_PUT_LONG(buf, objp->curfiles); IZDR_PUT_LONG(buf, objp->btimeleft); IZDR_PUT_LONG(buf, objp->ftimeleft); } return TRUE; } else if (zdrs->x_op == ZDR_DECODE) { buf = ZDR_INLINE (zdrs, 10 * BYTES_PER_ZDR_UNIT); if (buf == NULL) { if (!zdr_int (zdrs, &objp->bsize)) return FALSE; if (!zdr_int (zdrs, &objp->active)) return FALSE; if (!zdr_int (zdrs, &objp->bhardlimit)) return FALSE; if (!zdr_int (zdrs, &objp->bsoftlimit)) return FALSE; if (!zdr_int (zdrs, &objp->curblocks)) return FALSE; if (!zdr_int (zdrs, &objp->fhardlimit)) return FALSE; if (!zdr_int (zdrs, &objp->fsoftlimit)) return FALSE; if (!zdr_int (zdrs, &objp->curfiles)) return FALSE; if (!zdr_int (zdrs, &objp->btimeleft)) return FALSE; if (!zdr_int (zdrs, &objp->ftimeleft)) return FALSE; } else { objp->bsize = IZDR_GET_LONG(buf); objp->active = IZDR_GET_LONG(buf); objp->bhardlimit = IZDR_GET_LONG(buf); objp->bsoftlimit = IZDR_GET_LONG(buf); objp->curblocks = IZDR_GET_LONG(buf); objp->fhardlimit = IZDR_GET_LONG(buf); objp->fsoftlimit = IZDR_GET_LONG(buf); objp->curfiles = IZDR_GET_LONG(buf); objp->btimeleft = IZDR_GET_LONG(buf); objp->ftimeleft = IZDR_GET_LONG(buf); } return TRUE; } if (!zdr_int (zdrs, &objp->bsize)) return FALSE; if (!zdr_int (zdrs, &objp->active)) return FALSE; if (!zdr_int (zdrs, &objp->bhardlimit)) return FALSE; if (!zdr_int (zdrs, &objp->bsoftlimit)) return FALSE; if (!zdr_int (zdrs, &objp->curblocks)) return FALSE; if (!zdr_int (zdrs, &objp->fhardlimit)) return FALSE; if (!zdr_int (zdrs, &objp->fsoftlimit)) return FALSE; if (!zdr_int (zdrs, &objp->curfiles)) return FALSE; if (!zdr_int (zdrs, &objp->btimeleft)) return FALSE; if (!zdr_int (zdrs, &objp->ftimeleft)) return FALSE; return TRUE; } uint32_t zdr_GETQUOTA1res (ZDR *zdrs, GETQUOTA1res *objp) { if (!zdr_rquotastat (zdrs, &objp->status)) return FALSE; switch (objp->status) { case RQUOTA_OK: if (!zdr_GETQUOTA1res_ok (zdrs, &objp->GETQUOTA1res_u.quota)) return FALSE; break; default: break; } return TRUE; } libnfs-libnfs-1.9.8/rquota/libnfs-raw-rquota.h000066400000000000000000000127251255745034100213370ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ /* * Please do not edit this file. * It was generated using rpcgen. */ #ifndef _RQUOTA_H_RPCGEN #define _RQUOTA_H_RPCGEN #include #ifdef __cplusplus extern "C" { #endif #define RQUOTAPATHLEN 1024 enum rquotastat { RQUOTA_OK = 1, RQUOTA_NOQUOTA = 2, RQUOTA_EPERM = 3, }; typedef enum rquotastat rquotastat; typedef char *exportpath; struct GETQUOTA1args { exportpath export; int uid; }; typedef struct GETQUOTA1args GETQUOTA1args; enum quotatype { RQUOTA_TYPE_UID = 0, RQUOTA_TYPE_GID = 1, }; typedef enum quotatype quotatype; struct GETQUOTA2args { exportpath export; quotatype type; int uid; }; typedef struct GETQUOTA2args GETQUOTA2args; struct GETQUOTA1res_ok { int bsize; int active; int bhardlimit; int bsoftlimit; int curblocks; int fhardlimit; int fsoftlimit; int curfiles; int btimeleft; int ftimeleft; }; typedef struct GETQUOTA1res_ok GETQUOTA1res_ok; struct GETQUOTA1res { rquotastat status; union { GETQUOTA1res_ok quota; } GETQUOTA1res_u; }; typedef struct GETQUOTA1res GETQUOTA1res; #define RQUOTA_PROGRAM 100011 #define RQUOTA_V1 1 #if defined(__STDC__) || defined(__cplusplus) #define RQUOTA1_NULL 0 extern void * rquota1_null_1(void *, void *); extern void * rquota1_null_1_svc(void *, struct svc_req *); #define RQUOTA1_GETQUOTA 1 extern GETQUOTA1res * rquota1_getquota_1(GETQUOTA1args *, void *); extern GETQUOTA1res * rquota1_getquota_1_svc(GETQUOTA1args *, struct svc_req *); #define RQUOTA1_GETACTIVEQUOTA 2 extern GETQUOTA1res * rquota1_getactivequota_1(GETQUOTA1args *, void *); extern GETQUOTA1res * rquota1_getactivequota_1_svc(GETQUOTA1args *, struct svc_req *); extern int rquota_program_1_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define RQUOTA1_NULL 0 extern void * rquota1_null_1(); extern void * rquota1_null_1_svc(); #define RQUOTA1_GETQUOTA 1 extern GETQUOTA1res * rquota1_getquota_1(); extern GETQUOTA1res * rquota1_getquota_1_svc(); #define RQUOTA1_GETACTIVEQUOTA 2 extern GETQUOTA1res * rquota1_getactivequota_1(); extern GETQUOTA1res * rquota1_getactivequota_1_svc(); extern int rquota_program_1_freeresult (); #endif /* K&R C */ #define RQUOTA_V2 2 #if defined(__STDC__) || defined(__cplusplus) #define RQUOTA2_NULL 0 extern void * rquota2_null_2(void *, void *); extern void * rquota2_null_2_svc(void *, struct svc_req *); #define RQUOTA2_GETQUOTA 1 extern GETQUOTA1res * rquota2_getquota_2(GETQUOTA2args *, void *); extern GETQUOTA1res * rquota2_getquota_2_svc(GETQUOTA2args *, struct svc_req *); #define RQUOTA2_GETACTIVEQUOTA 2 extern GETQUOTA1res * rquota2_getactivequota_2(GETQUOTA2args *, void *); extern GETQUOTA1res * rquota2_getactivequota_2_svc(GETQUOTA2args *, struct svc_req *); extern int rquota_program_2_freeresult (void *, zdrproc_t, caddr_t); #else /* K&R C */ #define RQUOTA2_NULL 0 extern void * rquota2_null_2(); extern void * rquota2_null_2_svc(); #define RQUOTA2_GETQUOTA 1 extern GETQUOTA1res * rquota2_getquota_2(); extern GETQUOTA1res * rquota2_getquota_2_svc(); #define RQUOTA2_GETACTIVEQUOTA 2 extern GETQUOTA1res * rquota2_getactivequota_2(); extern GETQUOTA1res * rquota2_getactivequota_2_svc(); extern int rquota_program_2_freeresult (); #endif /* K&R C */ /* the zdr functions */ #if defined(__STDC__) || defined(__cplusplus) extern uint32_t zdr_rquotastat (ZDR *, rquotastat*); extern uint32_t zdr_exportpath (ZDR *, exportpath*); extern uint32_t zdr_GETQUOTA1args (ZDR *, GETQUOTA1args*); extern uint32_t zdr_quotatype (ZDR *, quotatype*); extern uint32_t zdr_GETQUOTA2args (ZDR *, GETQUOTA2args*); extern uint32_t zdr_GETQUOTA1res_ok (ZDR *, GETQUOTA1res_ok*); extern uint32_t zdr_GETQUOTA1res (ZDR *, GETQUOTA1res*); #else /* K&R C */ extern uint32_t zdr_rquotastat (); extern uint32_t zdr_exportpath (); extern uint32_t zdr_GETQUOTA1args (); extern uint32_t zdr_quotatype (); extern uint32_t zdr_GETQUOTA2args (); extern uint32_t zdr_GETQUOTA1res_ok (); extern uint32_t zdr_GETQUOTA1res (); #endif /* K&R C */ #ifdef __cplusplus } #endif #endif /* !_RQUOTA_H_RPCGEN */ libnfs-libnfs-1.9.8/rquota/rquota.c000066400000000000000000000133271255745034100172670ustar00rootroot00000000000000/* Copyright (C) 2010 by Ronnie Sahlberg This program 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 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 Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program; if not, see . */ #ifdef WIN32 #include "win32_compat.h" #endif/*WIN32*/ #include #include #include #include "libnfs-zdr.h" #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-private.h" #include "libnfs-raw-rquota.h" char *rquotastat_to_str(int error) { switch (error) { case RQUOTA_OK: return "RQUOTA_OK"; break; case RQUOTA_NOQUOTA: return "RQUOTA_NOQUOTA"; break; case RQUOTA_EPERM: return "RQUOTA_EPERM"; break; }; return "unknown rquota error"; } int rquotastat_to_errno(int error) { switch (error) { case RQUOTA_OK: return 0; break; case RQUOTA_NOQUOTA: return -ENOENT; break; case RQUOTA_EPERM: return -EPERM; break; }; return -ENOENT; } int rpc_rquota1_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V1, RQUOTA1_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota1/null call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota1/null call"); rpc_free_pdu(rpc, pdu); return -2; } return 0; } int rpc_rquota1_getquota_async(struct rpc_context *rpc, rpc_cb cb, char *export, int uid, void *private_data) { struct rpc_pdu *pdu; GETQUOTA1args args; pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V1, RQUOTA1_GETQUOTA, cb, private_data, (zdrproc_t)zdr_GETQUOTA1res, sizeof(GETQUOTA1res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota1/getquota call"); return -1; } args.export = export; args.uid = uid; if (zdr_GETQUOTA1args(&pdu->zdr, &args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode GETQUOTA1args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota1/getquota call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_rquota1_getactivequota_async(struct rpc_context *rpc, rpc_cb cb, char *export, int uid, void *private_data) { struct rpc_pdu *pdu; GETQUOTA1args args; pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V1, RQUOTA1_GETACTIVEQUOTA, cb, private_data, (zdrproc_t)zdr_GETQUOTA1res, sizeof(GETQUOTA1res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota1/getactivequota call"); return -1; } args.export = export; args.uid = uid; if (zdr_GETQUOTA1args(&pdu->zdr, &args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode GETQUOTA1args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota1/getactivequota call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_rquota2_null_async(struct rpc_context *rpc, rpc_cb cb, void *private_data) { struct rpc_pdu *pdu; pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V2, RQUOTA2_NULL, cb, private_data, (zdrproc_t)zdr_void, 0); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota2/null call"); return -1; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota2/null call"); rpc_free_pdu(rpc, pdu); return -2; } return 0; } int rpc_rquota2_getquota_async(struct rpc_context *rpc, rpc_cb cb, char *export, int type, int uid, void *private_data) { struct rpc_pdu *pdu; GETQUOTA2args args; pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V2, RQUOTA2_GETQUOTA, cb, private_data, (zdrproc_t)zdr_GETQUOTA1res, sizeof(GETQUOTA1res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota2/getquota call"); return -1; } args.export = export; args.type = type; args.uid = uid; if (zdr_GETQUOTA2args(&pdu->zdr, &args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode GETQUOTA2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota2/getquota call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } int rpc_rquota2_getactivequota_async(struct rpc_context *rpc, rpc_cb cb, char *export, int type, int uid, void *private_data) { struct rpc_pdu *pdu; GETQUOTA2args args; pdu = rpc_allocate_pdu(rpc, RQUOTA_PROGRAM, RQUOTA_V2, RQUOTA2_GETACTIVEQUOTA, cb, private_data, (zdrproc_t)zdr_GETQUOTA1res, sizeof(GETQUOTA1res)); if (pdu == NULL) { rpc_set_error(rpc, "Out of memory. Failed to allocate pdu for rquota2/getactivequota call"); return -1; } args.export = export; args.type = type; args.uid = uid; if (zdr_GETQUOTA2args(&pdu->zdr, &args) == 0) { rpc_set_error(rpc, "ZDR error: Failed to encode GETQUOTA2args"); rpc_free_pdu(rpc, pdu); return -2; } if (rpc_queue_pdu(rpc, pdu) != 0) { rpc_set_error(rpc, "Out of memory. Failed to queue pdu for rquota2/getactivequota call"); rpc_free_pdu(rpc, pdu); return -3; } return 0; } libnfs-libnfs-1.9.8/rquota/rquota.x000066400000000000000000000053751255745034100173200ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg All rights reserved. Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: 1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. The views and conclusions contained in the software and documentation are those of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ const RQUOTAPATHLEN = 1024; /* Guess this is max. It is max for mount so probably rquota too */ enum rquotastat { RQUOTA_OK = 1, RQUOTA_NOQUOTA = 2, RQUOTA_EPERM = 3 }; typedef string exportpath; struct GETQUOTA1args { exportpath export; int uid; }; enum quotatype { RQUOTA_TYPE_UID = 0, RQUOTA_TYPE_GID = 1 }; struct GETQUOTA2args { exportpath export; quotatype type; int uid; }; struct GETQUOTA1res_ok { int bsize; int active; int bhardlimit; int bsoftlimit; int curblocks; int fhardlimit; int fsoftlimit; int curfiles; int btimeleft; int ftimeleft; }; union GETQUOTA1res switch (rquotastat status) { case RQUOTA_OK: GETQUOTA1res_ok quota; default: void; }; program RQUOTA_PROGRAM { version RQUOTA_V1 { void RQUOTA1_NULL(void) = 0; GETQUOTA1res RQUOTA1_GETQUOTA(GETQUOTA1args) = 1; GETQUOTA1res RQUOTA1_GETACTIVEQUOTA(GETQUOTA1args) = 2; } = 1; version RQUOTA_V2 { void RQUOTA2_NULL(void) = 0; GETQUOTA1res RQUOTA2_GETQUOTA(GETQUOTA2args) = 1; GETQUOTA1res RQUOTA2_GETACTIVEQUOTA(GETQUOTA2args) = 2; } = 2; } = 100011; libnfs-libnfs-1.9.8/utils/000077500000000000000000000000001255745034100154275ustar00rootroot00000000000000libnfs-libnfs-1.9.8/utils/Makefile.am000066400000000000000000000003341255745034100174630ustar00rootroot00000000000000bin_PROGRAMS = nfs-cat nfs-cp nfs-ls AM_CPPFLAGS = \ -I$(abs_top_srcdir)/include \ -I$(abs_top_srcdir)/include/nfsc \ -I$(abs_top_srcdir)/mount \ "-D_U_=__attribute__((unused))" AM_LDFLAGS = ../lib/.libs/libnfs.la libnfs-libnfs-1.9.8/utils/nfs-cat.c000066400000000000000000000107761255745034100171410ustar00rootroot00000000000000/* Copyright (C) by Ronnie Sahlberg 2015 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 . */ #define _FILE_OFFSET_BITS 64 #define _GNU_SOURCE #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #pragma comment(lib, "ws2_32.lib") WSADATA wsaData; #else #include #include #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" struct file_context { int fd; struct nfs_context *nfs; struct nfsfh *nfsfh; struct nfs_url *url; }; void usage(void) { fprintf(stderr, "Usage: nfs-cat \n"); fprintf(stderr, " cat an nfs file.\n"); exit(0); } static void free_file_context(struct file_context *file_context) { if (file_context->fd != -1) { close(file_context->fd); } if (file_context->nfsfh != NULL) { nfs_close(file_context->nfs, file_context->nfsfh); } if (file_context->nfs != NULL) { nfs_destroy_context(file_context->nfs); } nfs_destroy_url(file_context->url); free(file_context); } static struct file_context * open_file(const char *url, int flags) { struct file_context *file_context; file_context = malloc(sizeof(struct file_context)); if (file_context == NULL) { fprintf(stderr, "Failed to malloc file_context\n"); return NULL; } file_context->fd = -1; file_context->nfs = NULL; file_context->nfsfh = NULL; file_context->url = NULL; file_context->nfs = nfs_init_context(); if (file_context->nfs == NULL) { fprintf(stderr, "failed to init context\n"); free_file_context(file_context); return NULL; } rpc_set_tcp_syncnt(nfs_get_rpc_context(file_context->nfs), 2); file_context->url = nfs_parse_url_full(file_context->nfs, url); if (file_context->url == NULL) { fprintf(stderr, "%s\n", nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } if (nfs_mount(file_context->nfs, file_context->url->server, file_context->url->path) != 0) { fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } if (flags == O_RDONLY) { if (nfs_open(file_context->nfs, file_context->url->file, flags, &file_context->nfsfh) != 0) { fprintf(stderr, "Failed to open file %s: %s\n", file_context->url->file, nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } } else { if (nfs_creat(file_context->nfs, file_context->url->file, 0660, &file_context->nfsfh) != 0) { fprintf(stderr, "Failed to creat file %s: %s\n", file_context->url->file, nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } } return file_context; } #define BUFSIZE 1024*1024 static char buf[BUFSIZE]; int main(int argc, char *argv[]) { int ret; struct file_context *nf; struct nfs_stat_64 st; uint64_t off; int64_t count; #ifdef WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { printf("Failed to start Winsock2\n"); return 10; } #endif #ifdef AROS aros_init_socket(); #endif if (argc < 2) { usage(); } nf = open_file(argv[1], O_RDONLY); if (nf == NULL) { fprintf(stderr, "Failed to open %s\n", argv[1]); exit(10); } if (nfs_fstat64(nf->nfs, nf->nfsfh, &st) < 0) { fprintf(stderr, "Failed to stat %s\n", argv[1]); exit(10); } off = 0; while (off < st.nfs_size) { count = st.nfs_size - off; if (count > BUFSIZE) { count = BUFSIZE; } count = nfs_pread(nf->nfs, nf->nfsfh, off, count, buf); if (count < 0) { fprintf(stderr, "Failed to read from file\n"); free_file_context(nf); return 10; } fwrite(buf, count, 1, stdout); off += count; } free_file_context(nf); return 0; } libnfs-libnfs-1.9.8/utils/nfs-cp.c000066400000000000000000000150421255745034100167630ustar00rootroot00000000000000/* Copyright (C) by Ronnie Sahlberg 2013 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 . */ #define _FILE_OFFSET_BITS 64 #define _GNU_SOURCE #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #pragma comment(lib, "ws2_32.lib") WSADATA wsaData; #else #include #include #endif #ifdef HAVE_POLL_H #include #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" struct file_context { int is_nfs; int fd; struct nfs_context *nfs; struct nfsfh *nfsfh; struct nfs_url *url; }; void usage(void) { fprintf(stderr, "Usage: nfs-cp \n"); fprintf(stderr, ", can either be a local file or " "an nfs URL.\n"); exit(0); } static void free_file_context(struct file_context *file_context) { if (file_context->fd != -1) { close(file_context->fd); } if (file_context->nfsfh != NULL) { nfs_close(file_context->nfs, file_context->nfsfh); } if (file_context->nfs != NULL) { nfs_destroy_context(file_context->nfs); } nfs_destroy_url(file_context->url); free(file_context); } static int fstat_file(struct file_context *fc, struct stat *st) { if (fc->is_nfs == 0) { return fstat(fc->fd, st); } else { int res; struct nfs_stat_64 nfs_st; res = nfs_fstat64(fc->nfs, fc->nfsfh, &nfs_st); st->st_dev = nfs_st.nfs_dev; st->st_ino = nfs_st.nfs_ino; st->st_mode = nfs_st.nfs_mode; st->st_nlink = nfs_st.nfs_nlink; st->st_uid = nfs_st.nfs_uid; st->st_gid = nfs_st.nfs_gid; st->st_rdev = nfs_st.nfs_rdev; st->st_size = nfs_st.nfs_size; st->st_blksize = nfs_st.nfs_blksize; st->st_blocks = nfs_st.nfs_blocks; st->st_atim.tv_sec = nfs_st.nfs_atime; st->st_mtim.tv_sec = nfs_st.nfs_mtime; st->st_ctim.tv_sec = nfs_st.nfs_ctime; return res; } } static int64_t file_pread(struct file_context *fc, char *buf, int64_t count, uint64_t off) { if (fc->is_nfs == 0) { lseek(fc->fd, off, SEEK_SET); return read(fc->fd, buf, count); } else { return nfs_pread(fc->nfs, fc->nfsfh, off, count, buf); } } static int64_t file_pwrite(struct file_context *fc, char *buf, int64_t count, uint64_t off) { if (fc->is_nfs == 0) { lseek(fc->fd, off, SEEK_SET); return write(fc->fd, buf, count); } else { return nfs_pwrite(fc->nfs, fc->nfsfh, off, count, buf); } } static struct file_context * open_file(const char *url, int flags) { struct file_context *file_context; file_context = malloc(sizeof(struct file_context)); if (file_context == NULL) { fprintf(stderr, "Failed to malloc file_context\n"); return NULL; } file_context->is_nfs = 0; file_context->fd = -1; file_context->nfs = NULL; file_context->nfsfh = NULL; file_context->url = NULL; if (strncmp(url, "nfs://", 6)) { file_context->is_nfs = 0; file_context->fd = open(url, flags, 0660); if (file_context->fd == -1) { fprintf(stderr, "Failed to open %s\n", url); free_file_context(file_context); return NULL; } return file_context; } file_context->is_nfs = 1; file_context->nfs = nfs_init_context(); if (file_context->nfs == NULL) { fprintf(stderr, "failed to init context\n"); free_file_context(file_context); return NULL; } file_context->url = nfs_parse_url_full(file_context->nfs, url); if (file_context->url == NULL) { fprintf(stderr, "%s\n", nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } if (nfs_mount(file_context->nfs, file_context->url->server, file_context->url->path) != 0) { fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } if (flags == O_RDONLY) { if (nfs_open(file_context->nfs, file_context->url->file, flags, &file_context->nfsfh) != 0) { fprintf(stderr, "Failed to open file %s: %s\n", file_context->url->file, nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } } else { if (nfs_creat(file_context->nfs, file_context->url->file, 0660, &file_context->nfsfh) != 0) { fprintf(stderr, "Failed to creat file %s: %s\n", file_context->url->file, nfs_get_error(file_context->nfs)); free_file_context(file_context); return NULL; } } return file_context; } #define BUFSIZE 1024*1024 static char buf[BUFSIZE]; int main(int argc, char *argv[]) { int ret; struct stat st; struct file_context *src; struct file_context *dst; uint64_t off; int64_t count; #ifdef WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { printf("Failed to start Winsock2\n"); return 10; } #endif #ifdef AROS aros_init_socket(); #endif if (argc != 3) { usage(); } src = open_file(argv[1], O_RDONLY); if (src == NULL) { fprintf(stderr, "Failed to open %s\n", argv[1]); return 10; } dst = open_file(argv[2], O_WRONLY|O_CREAT|O_TRUNC); if (dst == NULL) { fprintf(stderr, "Failed to open %s\n", argv[2]); free_file_context(src); return 10; } if (fstat_file(src, &st) != 0) { fprintf(stderr, "Failed to fstat source file\n"); free_file_context(src); free_file_context(dst); return 10; } off = 0; while (off < st.st_size) { count = st.st_size - off; if (count > BUFSIZE) { count = BUFSIZE; } count = file_pread(src, buf, count, off); if (count < 0) { fprintf(stderr, "Failed to read from source file\n"); free_file_context(src); free_file_context(dst); return 10; } count = file_pwrite(dst, buf, count, off); if (count < 0) { fprintf(stderr, "Failed to write to dest file\n"); free_file_context(src); free_file_context(dst); return 10; } off += count; } printf("copied %d bytes\n", (int)off); free_file_context(src); free_file_context(dst); return 0; } libnfs-libnfs-1.9.8/utils/nfs-ls.c000066400000000000000000000136311255745034100170010ustar00rootroot00000000000000/* Copyright (C) by Ronnie Sahlberg 2010 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 . */ #define _FILE_OFFSET_BITS 64 #define _GNU_SOURCE #ifdef HAVE_CONFIG_H #include "config.h" #endif #ifdef AROS #include "aros_compat.h" #endif #ifdef WIN32 #include "win32_compat.h" #pragma comment(lib, "ws2_32.lib") WSADATA wsaData; #define PRId64 "ll" #else #include #include #include #ifndef AROS #ifdef ANDROID #define statvfs statfs #include #else #include #endif #endif #endif #ifdef HAVE_UNISTD_H #include #endif #include #include #include #include #include #include #include "libnfs.h" #include "libnfs-raw.h" #include "libnfs-raw-mount.h" struct client { char *server; char *export; uint32_t mount_port; int is_finished; }; int recursive = 0, summary = 0, discovery = 0; void print_usage(void) { fprintf(stderr, "Usage: nfs-ls [-?|--help|--usage] [-R|--recursive] [-s|--summary] [-D|--discovery] \n"); } int process_server(const char *server) { struct exportnode *exports; struct exportnode *export; exports = mount_getexports(server); if (exports == NULL) { fprintf(stderr, "Failed to get exports for server %s.\n", server); return -1; } for (export=exports; export; export = export->ex_next) { printf("nfs://%s%s\n", server, export->ex_dir); } mount_free_export_list(exports); return 0; } void process_dir(struct nfs_context *nfs, char *dir, int level) { int ret; struct nfsdirent *nfsdirent; struct nfsdir *nfsdir; if (!level) { printf("Recursion detected!\n"); exit(10); } ret = nfs_opendir(nfs, dir, &nfsdir); if (ret != 0) { printf("Failed to opendir(\"%s\") %s\n", dir, nfs_get_error(nfs)); exit(10); } while((nfsdirent = nfs_readdir(nfs, nfsdir)) != NULL) { char path[1024]; if (!strcmp(nfsdirent->name, ".") || !strcmp(nfsdirent->name, "..")) { continue; } snprintf(path, 1024, "%s/%s", dir, nfsdirent->name); switch (nfsdirent->mode & S_IFMT) { case S_IFLNK: printf("l"); break; case S_IFREG: printf("-"); break; case S_IFDIR: printf("d"); break; case S_IFCHR: printf("c"); break; case S_IFBLK: printf("b"); break; } printf("%c%c%c", "-r"[!!(nfsdirent->mode & S_IRUSR)], "-w"[!!(nfsdirent->mode & S_IWUSR)], "-x"[!!(nfsdirent->mode & S_IXUSR)] ); printf("%c%c%c", "-r"[!!(nfsdirent->mode & S_IRGRP)], "-w"[!!(nfsdirent->mode & S_IWGRP)], "-x"[!!(nfsdirent->mode & S_IXGRP)] ); printf("%c%c%c", "-r"[!!(nfsdirent->mode & S_IROTH)], "-w"[!!(nfsdirent->mode & S_IWOTH)], "-x"[!!(nfsdirent->mode & S_IXOTH)] ); printf(" %2d", (int)nfsdirent->nlink); printf(" %5d", (int)nfsdirent->uid); printf(" %5d", (int)nfsdirent->gid); printf(" %12" PRId64, nfsdirent->size); printf(" %s\n", path + 1); if (recursive && (nfsdirent->mode & S_IFMT) == S_IFDIR) { process_dir(nfs, path, level - 1); } } nfs_closedir(nfs, nfsdir); } int main(int argc, char *argv[]) { struct nfs_context *nfs = NULL; int i, ret = 1; struct client client; struct statvfs stvfs; struct nfs_url *url = NULL; #ifdef WIN32 if (WSAStartup(MAKEWORD(2,2), &wsaData) != 0) { printf("Failed to start Winsock2\n"); exit(10); } #endif #ifdef AROS aros_init_socket(); #endif if (argc < 2) { fprintf(stderr, "No URL specified.\n"); goto finished; } for (i=1; i < argc -1; i++) { if (!strcmp(argv[i], "-R") || !strcmp(argv[i], "--recursive")) { recursive++; } else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--summary")) { summary++; } else if (!strcmp(argv[i], "-D") || !strcmp(argv[i], "--discovery")) { discovery++; } else{ goto finished; } } nfs = nfs_init_context(); if (nfs == NULL) { printf("failed to init context\n"); goto finished; } if (discovery) { url = nfs_parse_url_incomplete(nfs, argv[argc - 1]); if (url == NULL) { fprintf(stderr, "%s\n", nfs_get_error(nfs)); goto finished; } if (!url->server) { struct nfs_server_list *srvrs; struct nfs_server_list *srv; srvrs = nfs_find_local_servers(); if (srvrs == NULL) { fprintf(stderr, "Failed to find local servers.\n"); goto finished; } for (srv=srvrs; srv; srv = srv->next) { if (recursive) { process_server(srv->addr); } else { printf("nfs://%s\n", srv->addr); } } free_nfs_srvr_list(srvrs); ret = 0; goto finished; } if (url->server && !url->path) { ret = process_server(url->server); goto finished; } nfs_destroy_url(url); } url = nfs_parse_url_dir(nfs, argv[argc - 1]); if (url == NULL) { fprintf(stderr, "%s\n", nfs_get_error(nfs)); goto finished; } client.server = url->server; client.export = url->path; client.is_finished = 0; if ((ret = nfs_mount(nfs, client.server, client.export)) != 0) { fprintf(stderr, "Failed to mount nfs share : %s\n", nfs_get_error(nfs)); goto finished; } process_dir(nfs, "", 16); if (summary) { if (nfs_statvfs(nfs, "", &stvfs) != 0) { goto finished; } printf("\n%12" PRId64 " of %12" PRId64 " bytes free.\n", stvfs.f_frsize * stvfs.f_bfree, stvfs.f_frsize * stvfs.f_blocks); } ret = 0; finished: if (ret > 0) { print_usage(); } nfs_destroy_url(url); if (nfs != NULL) { nfs_destroy_context(nfs); } return ret; } libnfs-libnfs-1.9.8/win32/000077500000000000000000000000001255745034100152315ustar00rootroot00000000000000libnfs-libnfs-1.9.8/win32/libnfs/000077500000000000000000000000001255745034100165065ustar00rootroot00000000000000libnfs-libnfs-1.9.8/win32/libnfs/libnfs.sln000066400000000000000000000151451255745034100205070ustar00rootroot00000000000000 Microsoft Visual Studio Solution File, Format Version 11.00 # Visual C++ Express 2010 Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "libnfs", "libnfs.vcxproj", "{7CAB9B67-6AA9-497F-A900-20D9D05049F5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfsclient-sync", "..\nfsclient-sync\nfsclient-sync.vcxproj", "{B907AC9A-50C5-4E43-97C3-27DC7241F6C5}" ProjectSection(ProjectDependencies) = postProject {7CAB9B67-6AA9-497F-A900-20D9D05049F5} = {7CAB9B67-6AA9-497F-A900-20D9D05049F5} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfsclient-async", "..\nfsclient-async\nfsclient-async.vcxproj", "{00EB73F2-8DA9-43DC-A0BB-5A09464DA4A0}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfsclient-bcast", "..\nfsclient-bcast\nfsclient-bcast.vcxproj", "{4F1B789D-B760-4B27-A5AD-D923765413F4}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfsclient-listservers", "..\nfsclient-listservers\nfsclient-listservers.vcxproj", "{C9EE015F-D35B-4DC6-B024-7C9C2C5D45E6}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfsclient-raw", "..\nfsclient-raw\nfsclient-raw.vcxproj", "{5C31C9BE-13AA-4012-A3C2-12A8042BE0B5}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfs-cp", "..\nfs-cp\nfs-cp.vcxproj", "{8C223950-DD30-4C89-BD5D-C105951FE2B6}" EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "nfs-ls", "..\nfs-ls\nfs-ls.vcxproj", "{43A2C9EF-338F-4326-9DF2-1CE0B1DA1C6B}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Win32 = Debug|Win32 Debug|x64 = Debug|x64 Release|Win32 = Release|Win32 Release|x64 = Release|x64 EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Debug|Win32.ActiveCfg = Debug|Win32 {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Debug|Win32.Build.0 = Debug|Win32 {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Debug|x64.ActiveCfg = Debug|x64 {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Debug|x64.Build.0 = Debug|x64 {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Release|Win32.ActiveCfg = Release|Win32 {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Release|Win32.Build.0 = Release|Win32 {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Release|x64.ActiveCfg = Release|x64 {7CAB9B67-6AA9-497F-A900-20D9D05049F5}.Release|x64.Build.0 = Release|x64 {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Debug|Win32.ActiveCfg = Debug|Win32 {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Debug|Win32.Build.0 = Debug|Win32 {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Debug|x64.ActiveCfg = Debug|x64 {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Debug|x64.Build.0 = Debug|x64 {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Release|Win32.ActiveCfg = Release|Win32 {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Release|Win32.Build.0 = Release|Win32 {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Release|x64.ActiveCfg = Release|x64 {B907AC9A-50C5-4E43-97C3-27DC7241F6C5}.Release|x64.Build.0 = Release|x64 {00EB73F2-8DA9-43DC-A0BB-5A09464DA4A0}.Debug|Win32.ActiveCfg = Debug|Win32 {00EB73F2-8DA9-43DC-A0BB-5A09464DA4A0}.Debug|Win32.Build.0 = Debug|Win32 {00EB73F2-8DA9-43DC-A0BB-5A09464DA4A0}.Debug|x64.ActiveCfg = Debug|x64 {00EB73F2-8DA9-43DC-A0BB-5A09464DA4A0}.Debug|x64.Build.0 = Debug|x64 {00EB73F2-8DA9-43DC-A0BB-5A09464DA4A0}.Release|Win32.ActiveCfg = Release|Win32 {00EB73F2-8DA9-43DC-A0BB-5A09464DA4A0}.Release|Win32.Build.0 = Release|Win32 {00EB73F2-8DA9-43DC-A0BB-5A09464DA4A0}.Release|x64.ActiveCfg = Release|x64 {00EB73F2-8DA9-43DC-A0BB-5A09464DA4A0}.Release|x64.Build.0 = Release|x64 {4F1B789D-B760-4B27-A5AD-D923765413F4}.Debug|Win32.ActiveCfg = Debug|Win32 {4F1B789D-B760-4B27-A5AD-D923765413F4}.Debug|Win32.Build.0 = Debug|Win32 {4F1B789D-B760-4B27-A5AD-D923765413F4}.Debug|x64.ActiveCfg = Debug|x64 {4F1B789D-B760-4B27-A5AD-D923765413F4}.Debug|x64.Build.0 = Debug|x64 {4F1B789D-B760-4B27-A5AD-D923765413F4}.Release|Win32.ActiveCfg = Release|Win32 {4F1B789D-B760-4B27-A5AD-D923765413F4}.Release|Win32.Build.0 = Release|Win32 {4F1B789D-B760-4B27-A5AD-D923765413F4}.Release|x64.ActiveCfg = Release|x64 {4F1B789D-B760-4B27-A5AD-D923765413F4}.Release|x64.Build.0 = Release|x64 {C9EE015F-D35B-4DC6-B024-7C9C2C5D45E6}.Debug|Win32.ActiveCfg = Debug|Win32 {C9EE015F-D35B-4DC6-B024-7C9C2C5D45E6}.Debug|Win32.Build.0 = Debug|Win32 {C9EE015F-D35B-4DC6-B024-7C9C2C5D45E6}.Debug|x64.ActiveCfg = Debug|x64 {C9EE015F-D35B-4DC6-B024-7C9C2C5D45E6}.Debug|x64.Build.0 = Debug|x64 {C9EE015F-D35B-4DC6-B024-7C9C2C5D45E6}.Release|Win32.ActiveCfg = Release|Win32 {C9EE015F-D35B-4DC6-B024-7C9C2C5D45E6}.Release|Win32.Build.0 = Release|Win32 {C9EE015F-D35B-4DC6-B024-7C9C2C5D45E6}.Release|x64.ActiveCfg = Release|x64 {C9EE015F-D35B-4DC6-B024-7C9C2C5D45E6}.Release|x64.Build.0 = Release|x64 {5C31C9BE-13AA-4012-A3C2-12A8042BE0B5}.Debug|Win32.ActiveCfg = Debug|Win32 {5C31C9BE-13AA-4012-A3C2-12A8042BE0B5}.Debug|Win32.Build.0 = Debug|Win32 {5C31C9BE-13AA-4012-A3C2-12A8042BE0B5}.Debug|x64.ActiveCfg = Debug|x64 {5C31C9BE-13AA-4012-A3C2-12A8042BE0B5}.Debug|x64.Build.0 = Debug|x64 {5C31C9BE-13AA-4012-A3C2-12A8042BE0B5}.Release|Win32.ActiveCfg = Release|Win32 {5C31C9BE-13AA-4012-A3C2-12A8042BE0B5}.Release|Win32.Build.0 = Release|Win32 {5C31C9BE-13AA-4012-A3C2-12A8042BE0B5}.Release|x64.ActiveCfg = Release|x64 {5C31C9BE-13AA-4012-A3C2-12A8042BE0B5}.Release|x64.Build.0 = Release|x64 {8C223950-DD30-4C89-BD5D-C105951FE2B6}.Debug|Win32.ActiveCfg = Debug|Win32 {8C223950-DD30-4C89-BD5D-C105951FE2B6}.Debug|Win32.Build.0 = Debug|Win32 {8C223950-DD30-4C89-BD5D-C105951FE2B6}.Debug|x64.ActiveCfg = Debug|x64 {8C223950-DD30-4C89-BD5D-C105951FE2B6}.Debug|x64.Build.0 = Debug|x64 {8C223950-DD30-4C89-BD5D-C105951FE2B6}.Release|Win32.ActiveCfg = Release|Win32 {8C223950-DD30-4C89-BD5D-C105951FE2B6}.Release|Win32.Build.0 = Release|Win32 {8C223950-DD30-4C89-BD5D-C105951FE2B6}.Release|x64.ActiveCfg = Release|x64 {8C223950-DD30-4C89-BD5D-C105951FE2B6}.Release|x64.Build.0 = Release|x64 {43A2C9EF-338F-4326-9DF2-1CE0B1DA1C6B}.Debug|Win32.ActiveCfg = Debug|Win32 {43A2C9EF-338F-4326-9DF2-1CE0B1DA1C6B}.Debug|Win32.Build.0 = Debug|Win32 {43A2C9EF-338F-4326-9DF2-1CE0B1DA1C6B}.Debug|x64.ActiveCfg = Debug|x64 {43A2C9EF-338F-4326-9DF2-1CE0B1DA1C6B}.Debug|x64.Build.0 = Debug|x64 {43A2C9EF-338F-4326-9DF2-1CE0B1DA1C6B}.Release|Win32.ActiveCfg = Release|Win32 {43A2C9EF-338F-4326-9DF2-1CE0B1DA1C6B}.Release|Win32.Build.0 = Release|Win32 {43A2C9EF-338F-4326-9DF2-1CE0B1DA1C6B}.Release|x64.ActiveCfg = Release|x64 {43A2C9EF-338F-4326-9DF2-1CE0B1DA1C6B}.Release|x64.Build.0 = Release|x64 EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection EndGlobal libnfs-libnfs-1.9.8/win32/libnfs/libnfs.vcxproj000066400000000000000000000332001255745034100213760ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {7CAB9B67-6AA9-497F-A900-20D9D05049F5} Win32Proj libnfs DynamicLibrary true MultiByte DynamicLibrary true MultiByte DynamicLibrary false true MultiByte DynamicLibrary false true MultiByte true ..\..\..\oncrpc-win32\win32\bin;$(LibraryPath) ..\..\..\oncrpc-win32\win32\bin;$(ExecutablePath) true ..\..\..\oncrpc-win32\win32\bin;$(LibraryPath) ..\..\..\oncrpc-win32\win32\bin;$(ExecutablePath) false ..\..\..\oncrpc-win32\win32\bin;$(LibraryPath) ..\..\..\oncrpc-win32\win32\bin;$(ExecutablePath) false ..\..\..\oncrpc-win32\win32\bin;$(LibraryPath) ..\..\..\oncrpc-win32\win32\bin;$(ExecutablePath) Level3 Disabled WIN32;NDEBUG;_WINDOWS;_USRDLL;_U_=;_USE_32BIT_TIME_T;__STDC_CONSTANT_MACROS;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs;..\..\lib Default 4996 Windows true ..\..\lib\libnfs-win32.def ws2_32.lib;%(AdditionalDependencies) MSVCRT Level3 Disabled WIN32;NDEBUG;_WINDOWS;_USRDLL;_U_=;__STDC_CONSTANT_MACROS;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs;..\..\lib Default 4996 Windows true ..\..\lib\libnfs-win32.def oncrpc.lib;ws2_32.lib;%(AdditionalDependencies) MSVCRT copy $(ProjectDir)..\..\nfs\nfs.x $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x rpcgen.exe -h $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x > $(ProjectDir)..\..\nfs\libnfs-raw-nfs.h rpcgen.exe -c $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x > $(ProjectDir)..\..\nfs\libnfs-raw-nfs.c copy $(ProjectDir)..\..\rquota\rquota.x $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x rpcgen.exe -h $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x > $(ProjectDir)..\..\rquota\libnfs-raw-rquota.h rpcgen.exe -c $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x > $(ProjectDir)..\..\rquota\libnfs-raw-rquota.c copy $(ProjectDir)..\..\portmap\portmap.x $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x rpcgen.exe -h $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x > $(ProjectDir)..\..\portmap\libnfs-raw-portmap.h rpcgen.exe -c $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x > $(ProjectDir)..\..\portmap\libnfs-raw-portmap.c copy $(ProjectDir)..\..\mount\mount.x $(ProjectDir)..\..\mount\libnfs-raw-mount.x rpcgen.exe -h $(ProjectDir)..\..\mount\libnfs-raw-mount.x > $(ProjectDir)..\..\mount\libnfs- rpcgen.exe -c $(ProjectDir)..\..\mount\libnfs-raw-mount.x > $(ProjectDir)..\..\mount\libnfs-raw-mount.c Level3 MaxSpeed true true WIN32;NDEBUG;_WINDOWS;_USRDLL;_U_=;_USE_32BIT_TIME_T;__STDC_CONSTANT_MACROS;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs;..\..\lib 4996 Windows true true true ws2_32.lib;%(AdditionalDependencies) ..\..\lib\libnfs-win32.def Level3 Full true true WIN32;NDEBUG;_WINDOWS;_USRDLL;_U_=;__STDC_CONSTANT_MACROS;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs;..\..\lib 4996 AnySuitable Speed Windows true true true oncrpc.lib;ws2_32.lib;%(AdditionalDependencies) ..\..\lib\libnfs-win32.def copy $(ProjectDir)..\..\nfs\nfs.x $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x rpcgen.exe -h $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x > $(ProjectDir)..\..\nfs\libnfs-raw-nfs.h rpcgen.exe -c $(ProjectDir)..\..\nfs\libnfs-raw-nfs.x > $(ProjectDir)..\..\nfs\libnfs-raw-nfs.c copy $(ProjectDir)..\..\rquota\rquota.x $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x rpcgen.exe -h $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x > $(ProjectDir)..\..\rquota\libnfs-raw-rquota.h rpcgen.exe -c $(ProjectDir)..\..\rquota\libnfs-raw-rquota.x > $(ProjectDir)..\..\rquota\libnfs-raw-rquota.c copy $(ProjectDir)..\..\portmap\portmap.x $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x rpcgen.exe -h $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x > $(ProjectDir)..\..\portmap\libnfs-raw-portmap.h rpcgen.exe -c $(ProjectDir)..\..\portmap\libnfs-raw-portmap.x > $(ProjectDir)..\..\portmap\libnfs-raw-portmap.c copy $(ProjectDir)..\..\mount\mount.x $(ProjectDir)..\..\mount\libnfs-raw-mount.x rpcgen.exe -h $(ProjectDir)..\..\mount\libnfs-raw-mount.x > $(ProjectDir)..\..\mount\libnfs-raw-mount.h rpcgen.exe -c $(ProjectDir)..\..\mount\libnfs-raw-mount.x > $(ProjectDir)..\..\mount\libnfs-raw-mount.c libnfs-libnfs-1.9.8/win32/libnfs/libnfs.vcxproj.filters000066400000000000000000000072561255745034100230610ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx {93995380-89BD-4b04-88EB-625FBE52EBFB} h;hpp;hxx;hm;inl;inc;xsd Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Source Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files Header Files libnfs-libnfs-1.9.8/win32/libnfs/version.rc000066400000000000000000000046521255745034100205300ustar00rootroot00000000000000// Microsoft Visual C++ generated resource script. // #ifdef APSTUDIO_INVOKED #ifndef APSTUDIO_READONLY_SYMBOLS #define _APS_NEXT_RESOURCE_VALUE 101 #define _APS_NEXT_COMMAND_VALUE 40001 #define _APS_NEXT_CONTROL_VALUE 1001 #define _APS_NEXT_SYMED_VALUE 101 #endif #endif #define APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 2 resource. // #include "afxres.h" ///////////////////////////////////////////////////////////////////////////// #undef APSTUDIO_READONLY_SYMBOLS ///////////////////////////////////////////////////////////////////////////// // Deutsch (Deutschland) resources #if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_DEU) LANGUAGE LANG_GERMAN, SUBLANG_GERMAN #ifdef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // TEXTINCLUDE // 1 TEXTINCLUDE BEGIN "resource1.h\0" END 2 TEXTINCLUDE BEGIN "#include ""afxres.h""\r\n" "\0" END 3 TEXTINCLUDE BEGIN "\r\n" "\0" END #endif // APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Version // VS_VERSION_INFO VERSIONINFO FILEVERSION 1,8,0,0 PRODUCTVERSION 1,8,0,0 FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L #else FILEFLAGS 0x0L #endif FILEOS 0x40004L FILETYPE 0x2L FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" BEGIN BLOCK "040704b0" BEGIN VALUE "CompanyName", "https://github.com/sahlberg/libnfs" VALUE "FileDescription", "LIBNFS is a client library for accessing NFS shares over a network." VALUE "FileVersion", "1.8.0.0" VALUE "InternalName", "libnfs.dll" VALUE "LegalCopyright", "Copyright (C) 2014" VALUE "OriginalFilename", "libnfs.dll" VALUE "ProductName", "libnfs" VALUE "ProductVersion", "1.8.0.0" END END BLOCK "VarFileInfo" BEGIN VALUE "Translation", 0x407, 1200 END END #endif // Deutsch (Deutschland) resources ///////////////////////////////////////////////////////////////////////////// #ifndef APSTUDIO_INVOKED ///////////////////////////////////////////////////////////////////////////// // // Generated from the TEXTINCLUDE 3 resource. // ///////////////////////////////////////////////////////////////////////////// #endif // not APSTUDIO_INVOKED libnfs-libnfs-1.9.8/win32/nfs-cp/000077500000000000000000000000001255745034100164175ustar00rootroot00000000000000libnfs-libnfs-1.9.8/win32/nfs-cp/nfs-cp.vcxproj000066400000000000000000000211131255745034100212200ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {8C223950-DD30-4C89-BD5D-C105951FE2B6} Win32Proj nfsclientsync Application true Unicode Application true Unicode Application false true Unicode Application false true Unicode true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) libnfs-libnfs-1.9.8/win32/nfs-cp/nfs-cp.vcxproj.filters000066400000000000000000000007731255745034100227000ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files libnfs-libnfs-1.9.8/win32/nfs-ls/000077500000000000000000000000001255745034100164335ustar00rootroot00000000000000libnfs-libnfs-1.9.8/win32/nfs-ls/nfs-ls.vcxproj000066400000000000000000000211131255745034100212500ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {43A2C9EF-338F-4326-9DF2-1CE0B1DA1C6B} Win32Proj nfsclientsync Application true Unicode Application true Unicode Application false true Unicode Application false true Unicode true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) libnfs-libnfs-1.9.8/win32/nfs-ls/nfs-ls.vcxproj.filters000066400000000000000000000007731255745034100227300ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files libnfs-libnfs-1.9.8/win32/nfsclient-async/000077500000000000000000000000001255745034100203315ustar00rootroot00000000000000libnfs-libnfs-1.9.8/win32/nfsclient-async/nfsclient-async.vcxproj000066400000000000000000000211241255745034100250460ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {00EB73F2-8DA9-43DC-A0BB-5A09464DA4A0} Win32Proj nfsclientsync Application true Unicode Application true Unicode Application false true Unicode Application false true Unicode true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) libnfs-libnfs-1.9.8/win32/nfsclient-async/nfsclient-async.vcxproj.filters000066400000000000000000000010041255745034100265100ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files libnfs-libnfs-1.9.8/win32/nfsclient-bcast/000077500000000000000000000000001255745034100203105ustar00rootroot00000000000000libnfs-libnfs-1.9.8/win32/nfsclient-bcast/nfsclient-bcast.vcxproj000066400000000000000000000211601255745034100250040ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {4F1B789D-B760-4B27-A5AD-D923765413F4} Win32Proj nfsclientsync Application true Unicode Application true Unicode Application false true Unicode Application false true Unicode true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs;..\..\portmap Console true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs;..\..\portmap Console true true true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) libnfs-libnfs-1.9.8/win32/nfsclient-bcast/nfsclient-bcast.vcxproj.filters000066400000000000000000000010041255745034100264460ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files libnfs-libnfs-1.9.8/win32/nfsclient-listservers/000077500000000000000000000000001255745034100216015ustar00rootroot00000000000000libnfs-libnfs-1.9.8/win32/nfsclient-listservers/nfsclient-listservers.vcxproj000066400000000000000000000211321255745034100275650ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {C9EE015F-D35B-4DC6-B024-7C9C2C5D45E6} Win32Proj nfsclientsync Application true Unicode Application true Unicode Application false true Unicode Application false true Unicode true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) libnfs-libnfs-1.9.8/win32/nfsclient-listservers/nfsclient-listservers.vcxproj.filters000066400000000000000000000010121255745034100312270ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files libnfs-libnfs-1.9.8/win32/nfsclient-raw/000077500000000000000000000000001255745034100200055ustar00rootroot00000000000000libnfs-libnfs-1.9.8/win32/nfsclient-raw/nfsclient-raw.vcxproj000066400000000000000000000211541255745034100242010ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {5C31C9BE-13AA-4012-A3C2-12A8042BE0B5} Win32Proj nfsclientsync Application true Unicode Application true Unicode Application false true Unicode Application false true Unicode true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs;..\..\rquota Console true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs;..\..\rquota Console true true true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) libnfs-libnfs-1.9.8/win32/nfsclient-raw/nfsclient-raw.vcxproj.filters000066400000000000000000000010021255745034100256360ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files libnfs-libnfs-1.9.8/win32/nfsclient-sync/000077500000000000000000000000001255745034100201705ustar00rootroot00000000000000libnfs-libnfs-1.9.8/win32/nfsclient-sync/nfsclient-sync.vcxproj000066400000000000000000000211231255745034100245430ustar00rootroot00000000000000 Debug Win32 Debug x64 Release Win32 Release x64 {B907AC9A-50C5-4E43-97C3-27DC7241F6C5} Win32Proj nfsclientsync Application true Unicode Application true Unicode Application false true Unicode Application false true Unicode true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) true ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) false ..\libnfs\Release;..\..\..\oncrpc-win32\win32\bin;..\..\bin;$(LibraryPath) Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 Disabled WIN32;_DEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) false true Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\include\nfsc;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;WS2_32.lib;%(AdditionalDependencies) Level3 MaxSpeed true true WIN32;NDEBUG;_CONSOLE;_WIN32_WINNT=0x0501;_U_=;ONCRPC_STATIC;%(PreprocessorDefinitions) ..\..\..\oncrpc-win32\win32\include;..\..\include;..\..\.;..\..\win32;..\..\mount;..\..\nfs Console true true true libnfs.lib;oncrpc.lib;WS2_32.lib;%(AdditionalDependencies) libnfs-libnfs-1.9.8/win32/nfsclient-sync/nfsclient-sync.vcxproj.filters000066400000000000000000000010031255745034100262050ustar00rootroot00000000000000 {4FC737F1-C7A5-4376-A066-2A32D752A2FF} cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx Source Files libnfs-libnfs-1.9.8/win32/win32_compat.c000066400000000000000000000115161255745034100177060ustar00rootroot00000000000000/* Copyright (c) 2006 by Dan Kennedy. Copyright (c) 2006 by Juliusz Chroboczek. 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. */ #ifndef WIN32 static int dummy ATTRIBUTE((unused)); #else #include "win32_compat.h" #include #include #undef poll #undef socket #undef connect #undef accept #undef shutdown #undef getpeername #undef sleep #undef inet_aton #undef gettimeofday #undef stat #define assert(a) /* Windows needs this header file for the implementation of inet_aton() */ #include int win32_inet_pton(int af, const char * src, void * dst) { struct sockaddr_in sa; int len = sizeof(SOCKADDR); int ret = -1; int strLen = strlen(src) + 1; #ifdef UNICODE wchar_t *srcNonConst = (wchar_t *)malloc(strLen*sizeof(wchar_t)); memset(srcNonConst, 0, strLen); MultiByteToWideChar(CP_ACP, 0, src, -1, srcNonConst, strLen); #else char *srcNonConst = (char *)malloc(strLen); memset(srcNonConst, 0, strLen); strncpy(srcNonConst, src, strLen); #endif if( WSAStringToAddress(srcNonConst,af,NULL,(LPSOCKADDR)&sa,&len) == 0 ) { ret = 1; } else { if( WSAGetLastError() == WSAEINVAL ) { ret = -1; } } free(srcNonConst); memcpy(dst, &sa.sin_addr, sizeof(struct in_addr)); return ret; } int win32_poll(struct pollfd *fds, unsigned int nfds, int timo) { struct timeval timeout, *toptr; fd_set ifds, ofds, efds, *ip, *op; unsigned int i; int rc; // Set up the file-descriptor sets in ifds, ofds and efds. FD_ZERO(&ifds); FD_ZERO(&ofds); FD_ZERO(&efds); for (i = 0, op = ip = 0; i < nfds; ++i) { fds[i].revents = 0; if(fds[i].events & (POLLIN|POLLPRI)) { ip = &ifds; FD_SET(fds[i].fd, ip); } if(fds[i].events & POLLOUT) { op = &ofds; FD_SET(fds[i].fd, op); } FD_SET(fds[i].fd, &efds); } // Set up the timeval structure for the timeout parameter if(timo < 0) { toptr = 0; } else { toptr = &timeout; timeout.tv_sec = timo / 1000; timeout.tv_usec = (timo - timeout.tv_sec * 1000) * 1000; } #ifdef DEBUG_POLL printf("Entering select() sec=%ld usec=%ld ip=%lx op=%lx\n", (long)timeout.tv_sec, (long)timeout.tv_usec, (long)ip, (long)op); #endif rc = select(0, ip, op, &efds, toptr); #ifdef DEBUG_POLL printf("Exiting select rc=%d\n", rc); #endif if(rc <= 0) return rc; if(rc > 0) { for (i = 0; i < nfds; ++i) { int fd = fds[i].fd; if(fds[i].events & (POLLIN|POLLPRI) && FD_ISSET(fd, &ifds)) fds[i].revents |= POLLIN; if(fds[i].events & POLLOUT && FD_ISSET(fd, &ofds)) fds[i].revents |= POLLOUT; if(FD_ISSET(fd, &efds)) // Some error was detected ... should be some way to know. fds[i].revents |= POLLHUP; #ifdef DEBUG_POLL printf("%d %d %d revent = %x\n", FD_ISSET(fd, &ifds), FD_ISSET(fd, &ofds), FD_ISSET(fd, &efds), fds[i].revents ); #endif } } return rc; } #if defined(_MSC_VER) || defined(_MSC_EXTENSIONS) #define DELTA_EPOCH_IN_MICROSECS 11644473600000000Ui64 #else #define DELTA_EPOCH_IN_MICROSECS 11644473600000000ULL #endif struct timezone { int tz_minuteswest; /* minutes W of Greenwich */ int tz_dsttime; /* type of dst correction */ }; int win32_gettimeofday(struct timeval *tv, struct timezone *tz) { FILETIME ft; unsigned __int64 tmpres = 0; static int tzflag; if (NULL != tv) { GetSystemTimeAsFileTime(&ft); tmpres |= ft.dwHighDateTime; tmpres <<= 32; tmpres |= ft.dwLowDateTime; /*converting file time to unix epoch*/ tmpres -= DELTA_EPOCH_IN_MICROSECS; tmpres /= 10; /*convert into microseconds*/ tv->tv_sec = (long)(tmpres / 1000000UL); tv->tv_usec = (long)(tmpres % 1000000UL); } if (NULL != tz) { if (!tzflag) { _tzset(); tzflag++; } tz->tz_minuteswest = _timezone / 60; tz->tz_dsttime = _daylight; } return 0; } #endif libnfs-libnfs-1.9.8/win32/win32_compat.h000066400000000000000000000063061255745034100177140ustar00rootroot00000000000000/* Copyright (c) 2006 by Dan Kennedy. Copyright (c) 2006 by Juliusz Chroboczek. 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. */ /*Adaptions by memphiz@xbmc.org*/ #ifndef win32_COMPAT_H_ #define win32_COMPAT_H_ #define NO_IPv6 1 #include #include #include #include #include #include #include typedef int uid_t; typedef int gid_t; typedef int socklen_t; #define S_IRUSR 0000400 #define S_IWUSR 0000200 #define S_IXUSR 0000100 #define S_IRWXG 0000070 /* RWX mask for group */ #define S_IRGRP 0000040 #define S_IWGRP 0000020 #define S_IXGRP 0000010 #define S_IRWXO 0000007 /* RWX mask for other */ #define S_IROTH 0000004 #define S_IWOTH 0000002 #define S_IXOTH 0000001 #define F_GETFL 3 #define F_SETFL 4 #ifndef S_IFLNK #define S_IFLNK 0xA000 /* Link */ #endif #ifndef S_IFIFO #define S_IFIFO 0x1000 /* FIFO */ #endif #ifndef S_IFBLK #define S_IFBLK 0x3000 /* Block: Is this ever set under w32? */ #endif #ifndef S_IFSOCK #define S_IFSOCK 0x0 /* not defined in mingw either */ #endif #ifndef major #define major(a) 0 #endif #ifndef minor #define minor(a) 0 #endif #define O_NONBLOCK 0x40000000 #define O_SYNC 0 #define MSG_DONTWAIT 0 #define ssize_t SSIZE_T #if(_WIN32_WINNT < 0x0600) #define POLLIN 0x0001 /* There is data to read */ #define POLLPRI 0x0002 /* There is urgent data to read */ #define POLLOUT 0x0004 /* Writing now will not block */ #define POLLERR 0x0008 /* Error condition */ #define POLLHUP 0x0010 /* Hung up */ #define POLLNVAL 0x0020 /* Invalid request: fd not open */ struct pollfd { SOCKET fd; /* file descriptor */ short events; /* requested events */ short revents; /* returned events */ }; #endif #define close closesocket #define ioctl ioctlsocket /* Wrapper macros to call misc. functions win32 is missing */ #define poll(x, y, z) win32_poll(x, y, z) #define inet_pton(x,y,z) win32_inet_pton(x,y,z) int win32_inet_pton(int af, const char * src, void * dst); int win32_poll(struct pollfd *fds, unsigned int nfsd, int timeout); int win32_gettimeofday(struct timeval *tv, struct timezone *tz); #define DllExport #endif//win32_COMPAT_H_ libnfs-libnfs-1.9.8/win32/win32_errnowrapper.h000066400000000000000000000026621255745034100211600ustar00rootroot00000000000000/* Copyright (c) 2014, Ronnie Sahlberg 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. */ #ifndef WIN32_ERRNOWRAPPER_H_ #define WIN32_ERRNOWRAPPER_H_ #undef errno #define errno WSAGetLastError() #undef EAGAIN #undef EWOULDBLOCK #undef EINTR #undef EINPROGRESS #define EWOULDBLOCK WSAEWOULDBLOCK #define EAGAIN WSAEWOULDBLOCK //same on windows #define EINTR WSAEINTR #define EINPROGRESS WSAEWOULDBLOCK //does not map to WSAEINPROGRESS ! #endif //WIN32_ERRNOWRAPPER_H_ libnfs-libnfs-1.9.8/win32/win32build.bat000066400000000000000000000056641255745034100177160ustar00rootroot00000000000000rem build script for win32 rem set the rem rem EDIT THESE set LIBNFS_BASE_DIR=.. rem END EDIT cd %LIBNFS_BASE_DIR% rem NFS rem cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd nfs\libnfs-raw-nfs.c -Fonfs\libnfs-raw-nfs.obj cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd nfs\nfs.c -Fonfs\nfs.obj cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd nfs\nfsacl.c -Fonfs\nfsacl.obj rem rem RQUOTA rem cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd rquota\libnfs-raw-rquota.c -Forquota\libnfs-raw-rquota.obj cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd rquota\rquota.c -Forquota\rquota.obj rem rem PORTMAP rem cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd portmap\libnfs-raw-portmap.c -Foportmap\libnfs-raw-portmap.obj cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd portmap\portmap.c -Foportmap\portmap.obj rem rem MOUNT rem cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd mount\libnfs-raw-mount.c -Fomount\libnfs-raw-mount.obj cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd mount\mount.c -Fomount\mount.obj rem rem generate core part of library rem cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd lib\init.c -Folib\init.obj cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" lib\pdu.c -Folib\pdu.obj cl /I. /Iinclude /Iwin32 -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" lib\socket.c -Folib\socket.obj cl /I. /Iinclude /Iwin32 /Imount /Infs -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" lib\libnfs.c -Folib\libnfs.obj cl /I. /Iinclude /Iwin32 /Imount /Infs -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" lib\libnfs-sync.c -Folib\libnfs-sync.obj rem rem generate win32 compat layer rem cl /I. -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" win32\win32_compat.c -Fowin32\win32_compat.obj rem rem create a linklibrary/dll rem lib /out:lib\libnfs.lib /def:lib\libnfs-win32.def nfs\nfs.obj nfs\nfsacl.obj nfs\libnfs-raw-nfs.obj rquota\rquota.obj rquota\libnfs-raw-rquota.obj mount\mount.obj mount\libnfs-raw-mount.obj portmap\portmap.obj portmap\libnfs-raw-portmap.obj lib\init.obj lib\pdu.obj lib\socket.obj lib\libnfs.obj lib\libnfs-sync.obj win32\win32_compat.obj link /DLL /out:lib\libnfs.dll /DEBUG /DEBUGTYPE:cv lib\libnfs.exp nfs\nfs.obj nfs\nfsacl.obj nfs\libnfs-raw-nfs.obj rquota\rquota.obj rquota\libnfs-raw-rquota.obj mount\mount.obj mount\libnfs-raw-mount.obj portmap\portmap.obj portmap\libnfs-raw-portmap.obj lib\init.obj lib\pdu.obj lib\socket.obj lib\libnfs.obj lib\libnfs-sync.obj win32\win32_compat.obj ws2_32.lib rem rem build a test application rem cl /I. /Iinclude /Iwin32 /Imount /Infs -Zi -Od -DWIN32 -D_WIN32_WINNT=0x0501 -MDd -D_U_="" examples\nfsclient-sync.c lib\libnfs.lib WS2_32.lib kernel32.lib mswsock.lib advapi32.lib wsock32.lib advapi32.lib libnfs-libnfs-1.9.8/win32build.bat000077500000000000000000000067241255745034100167550ustar00rootroot00000000000000rem build script for win32 rem set the rem rem NFS rem cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd nfs\libnfs-raw-nfs.c -Fonfs\libnfs-raw-nfs.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd nfs\nfs.c -Fonfs\nfs.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd nfs\nfsacl.c -Fonfs\nfsacl.obj rem rem RQUOTA rem cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd rquota\libnfs-raw-rquota.c -Forquota\libnfs-raw-rquota.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd rquota\rquota.c -Forquota\rquota.obj rem rem PORTMAP rem cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd portmap\libnfs-raw-portmap.c -Foportmap\libnfs-raw-portmap.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd portmap\portmap.c -Foportmap\portmap.obj rem rem MOUNT rem cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd mount\libnfs-raw-mount.c -Fomount\libnfs-raw-mount.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd mount\mount.c -Fomount\mount.obj rem rem generate core part of library rem cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd lib\init.c -Folib\init.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" lib\pdu.c -Folib\pdu.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" lib\socket.c -Folib\socket.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude /Imount /Infs -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" lib\libnfs.c -Folib\libnfs.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude /Imount /Infs -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" lib\libnfs-sync.c -Folib\libnfs-sync.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude /Imount /Infs -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" lib\libnfs-zdr.c -Folib\libnfs-zdr.obj cl /I. /Iwin32 /Iinclude/nfsc /Iinclude /Imount /Infs -Zi -Od -c -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" win32\win32_compat.c -Fowin32\win32_compat.obj rem rem create a linklibrary/dll rem lib /out:lib\libnfs.lib /def:lib\libnfs-win32.def nfs\nfs.obj nfs\nfsacl.obj nfs\libnfs-raw-nfs.obj rquota\rquota.obj rquota\libnfs-raw-rquota.obj mount\mount.obj mount\libnfs-raw-mount.obj portmap\portmap.obj portmap\libnfs-raw-portmap.obj lib\init.obj lib\pdu.obj lib\socket.obj lib\libnfs.obj lib\libnfs-sync.obj lib\libnfs-zdr.obj win32\win32_compat.obj link /DLL /out:lib\libnfs.dll /DEBUG /DEBUGTYPE:cv lib\libnfs.exp nfs\nfs.obj nfs\nfsacl.obj nfs\libnfs-raw-nfs.obj rquota\rquota.obj rquota\libnfs-raw-rquota.obj mount\mount.obj mount\libnfs-raw-mount.obj portmap\portmap.obj portmap\libnfs-raw-portmap.obj lib\init.obj lib\pdu.obj lib\socket.obj lib\libnfs.obj lib\libnfs-sync.obj lib\libnfs-zdr.obj win32\win32_compat.obj ws2_32.lib rem rem build a test application rem cl /I. /Iwin32 /Iinclude/nfsc /Iinclude /Imount /Infs -Zi -Od -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" examples\nfs-ls.c lib\libnfs.lib WS2_32.lib kernel32.lib mswsock.lib advapi32.lib wsock32.lib advapi32.lib cl /I. /Iwin32 /Iinclude/nfsc /Iinclude /Imount /Infs -Zi -Od -DWIN32 -D_WIN32_WINNT=0x0600 -MDd -D_U_="" examples\nfs-cp.c lib\libnfs.lib WS2_32.lib kernel32.lib mswsock.lib advapi32.lib wsock32.lib advapi32.lib